最簡單的Shiro免密登陸(springboot)

思路比較簡單,實現也簡單,要的就是簡單! 實際項目中可以此基礎上封裝

重寫UsernamePasswordToken 中 getCredentials() 方法。所以新增了類NoPwdToken

UserRealm類中的 doGetAuthenticationInfo(AuthenticationToken authcToken) 方法執行時,判斷參數authcToken的類型如果是NoPwdToken類型,則返回值改爲getCredentials()方法對應的驗證信息。(即:SimpleHash simpleHash = new SimpleHash("SHA-256", "123456", null, 16);)。

 

1、增加類:NoPwdToken (關鍵地方是20行重寫的方法)

import org.apache.shiro.authc.UsernamePasswordToken;

public class NoPwdToken extends UsernamePasswordToken {

	public NoPwdToken(String username) {
		this.username = username;
	}

	private String username;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	@Override
	public Object getCredentials() {
          //這裏和下方的123456對應,也可以別的,一致即可。
		return "123456";
	}
}

 

2、修改UserRealm類中 的 doGetAuthenticationInfo(AuthenticationToken authcToken) 方法。(關鍵地方是2-13行)

	// 判斷是否免密登陸類型
	if (authcToken instanceof NoPwdToken) {
		// 免密登陸
		NoPwdToken token = (NoPwdToken) authcToken;
		SysUserEntity user = sysUserDao.selectByUserName(token.getUsername());
		if (user != null) {
            //這裏和上面的123456對應,也可以別的,一致即可。 
			SimpleHash simpleHash = new SimpleHash("SHA-256", "123456", null, 16);
			return new SimpleAuthenticationInfo(user, simpleHash, this.getClass().getSimpleName());
		} else {
			return null;
		}
	} else {
		// 默認的登陸方式
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		user.setUsername(token.getUsername());
	}

 

 

測試:

	/**
	 * 免密登陸
	 */
	@SysLog("免密登陸")
	@ResponseBody
	@RequestMapping(value = "/sys/nopwdlogin")
	public R nopwdlogin(@RequestParam Map<String, String> params, HttpServletRequest req, HttpServletResponse res) {
		String username = params.get("username");

		try {
			if (StringUtil.isBlank(username)) {
				return R.error("用戶名不能爲空");
			}
			Subject subject = SecurityUtils.getSubject();
			if (null != subject.getPrincipal()) {
				// 已經登陸過的情況
				res.sendRedirect("http://localhost/web/index.html");
				return R.ok().put("user", ShiroUtils.getUserEntity());
			}

			// 使用自定義Token
			NoPwdToken ssoToken = new NoPwdToken(username);
			subject.login(ssoToken);

		} catch (UnknownAccountException e) {
			return R.error(e.getMessage());
		} catch (IncorrectCredentialsException e) {
			return R.error("賬號或密碼不正確");
		} catch (LockedAccountException e) {
			return R.error("賬號已被鎖定,請聯繫管理員");
		} catch (AuthenticationException e) {
			return R.error("賬戶驗證失敗");
		} catch (Exception e) {
			return R.error("未知異常");
		}
		SysUserEntity sysUser = ShiroUtils.getUserEntity();
		sysUser.setPassword(null);
		try {
			res.sendRedirect("http://localhost/web/index.html");
		} catch (IOException e) {
			e.printStackTrace();
		}
		return R.ok().put("user", sysUser);
	}

 

發送請求:http://localhost:9000/sys/nopwdlogin?username=yuer

 

 

其他問題:

 1、如果加密類型和上方不同,可以參考 org.apache.shiro.authc.credential.HashedCredentialsMatcher 中 hashProvidedCredentials 方法。斷點打在這裏就可以看到了,如圖


 

2、用戶輸入密碼和實際密碼比較方法具體位置在 org.apache.shiro.authc.credential.HashedCredentialsMatcher 中 doCredentialsMatch 方法。如下圖:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章