Shiro 实现免密登陆
生活随笔
收集整理的這篇文章主要介紹了
Shiro 实现免密登陆
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
需求:對(duì)接第三方登陸,實(shí)現(xiàn)繞過原有Shiro認(rèn)證登陸。
文章目錄
- 一、實(shí)現(xiàn)思路
- 1. 現(xiàn)狀分析
- 2. 用戶來源
- 3. 所屬范圍
- 二、實(shí)現(xiàn)方案
- 2.1. 自定義登錄認(rèn)證規(guī)則
- 2.2. Shiro認(rèn)證枚舉
- 2.3. 密碼和非密碼登錄
- 2.4. 規(guī)則配置
- 2.5. 自定義Realm
- 2.6. 案例使用
一、實(shí)現(xiàn)思路
1. 現(xiàn)狀分析
系統(tǒng)權(quán)框架默認(rèn)使用Shiro 認(rèn)證授權(quán)機(jī)制
2. 用戶來源
從統(tǒng)一認(rèn)證平臺(tái)登錄跳轉(zhuǎn)過來的用戶
3. 所屬范圍
登錄限制由統(tǒng)一認(rèn)證平臺(tái)去做,但是,跳轉(zhuǎn)過來的用戶仍然走您本系統(tǒng)的登錄流程,只是走本系統(tǒng)的登錄流程時(shí),想跳過Shiro 對(duì)用戶密碼的校驗(yàn),校驗(yàn)所屬范圍為Shiro 認(rèn)證機(jī)制,其他功能照舊;
二、實(shí)現(xiàn)方案
2.1. 自定義登錄認(rèn)證規(guī)則
package com.gblfy.config.skipshiro;import com.gblfy.config.skipshiro.enums.ShiroApproveLoginType; import org.apache.shiro.authc.UsernamePasswordToken;/*** 自定義token 實(shí)現(xiàn)免密和密碼登錄* <p>* 1.賬號(hào)密碼登陸(password)* 2.免密登陸(nopassword)* </p>** @author gblfy* @date 2021-10-22*/ public class EasyUsernameToken extends UsernamePasswordToken {private static final long serialVersionUID = -2564928913725078138L;private ShiroApproveLoginType type;public EasyUsernameToken() {super();}/*** 免密登錄*/public EasyUsernameToken(String username) {super(username, "", false, null);this.type = ShiroApproveLoginType.NOPASSWD;}/*** 賬號(hào)密碼登錄*/public EasyUsernameToken(String username, String password, boolean rememberMe) {super(username, password, rememberMe, null);this.type = ShiroApproveLoginType.PASSWORD;}public ShiroApproveLoginType getType() {return type;}public void setType(ShiroApproveLoginType type) {this.type = type;}}2.2. Shiro認(rèn)證枚舉
package com.gblfy.config.skipshiro.enums;/*** Shiro認(rèn)證枚舉* @author gblfy* @date 2021-10-22*/ public enum ShiroApproveLoginType {/** 密碼登錄 */PASSWORD("PASSWORD"),/** 密碼登錄 */NOPASSWD("NOPASSWORD");/** 狀態(tài)值 */private String code;private ShiroApproveLoginType(String code) {this.code = code;}public String getCode() {return code;} }2.3. 密碼和非密碼登錄
package com.gblfy.config.skipshiro;import com.gblfy.config.skipshiro.enums.ShiroApproveLoginType; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.credential.HashedCredentialsMatcher;/*** 自定義登錄認(rèn)證方案* <p>* 1.免密登錄,不加密* 2.密碼登錄,md5加密* </p>** @author gblfy* @date 2021-10-22*/ public class EasyCredentialsMatch extends HashedCredentialsMatcher {/*** 重寫方法* 區(qū)分 密碼和非密碼登錄* 此次無需記錄登錄次數(shù) 詳情看SysPasswordService*/@Overridepublic boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {EasyUsernameToken easyUsernameToken = (EasyUsernameToken) token;//免密登錄,不驗(yàn)證密碼if (ShiroApproveLoginType.NOPASSWD.equals(easyUsernameToken.getType())) {return true;}//密碼登錄Object tokenHashedCredentials = hashProvidedCredentials(token, info);Object accountCredentials = getCredentials(info);return equals(tokenHashedCredentials, accountCredentials);} }2.4. 規(guī)則配置
@Beanpublic EasyCredentialsMatch customCredentialsMatch() {EasyCredentialsMatch customCredentialsMatch = new EasyCredentialsMatch();customCredentialsMatch.setHashAlgorithmName("md5");customCredentialsMatch.setHashIterations(3);customCredentialsMatch.setStoredCredentialsHexEncoded(true);return customCredentialsMatch;}2.5. 自定義Realm
權(quán)限認(rèn)證 保持默認(rèn),修改登錄認(rèn)證
public class UserRealm extends AuthorizingRealm {/*** 權(quán)限認(rèn)證 */@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//權(quán)限認(rèn)證 代碼省略}/*** 登錄認(rèn)證*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {EasyUsernameToken upToken = (EasyUsernameToken) token;String username = upToken.getUsername();SysUser user = null;// 密碼登錄if (upToken.getType().getCode().equals(LoginType.PASSWORD.getCode())) {String password;if (upToken.getPassword() != null) {password = new String(upToken.getPassword());try {user = loginService.login(username, password);} catch (Exception e) {log.info("對(duì)用戶[" + username + "]進(jìn)行登錄驗(yàn)證..驗(yàn)證未通過{}", e.getMessage());throw new AuthenticationException(e.getMessage(), e);}}} else if (upToken.getType().getCode().equals(LoginType.NOPASSWD.getCode())) {// 第三方登錄 TODO}SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, upToken.getPassword(), getName());return info;} }2.6. 案例使用
public AjaxResult login(String username, String password, Boolean rememberMe) {EasyUsernameToken token = new EasyUsernameToken(username, password, rememberMe);Subject subject = SecurityUtils.getSubject();try {subject.login(token);return success();} catch (AuthenticationException e) {String msg = "用戶或密碼錯(cuò)誤";if (StringUtils.isNotEmpty(e.getMessage())) {msg = e.getMessage();}return error(msg);}}總結(jié)
以上是生活随笔為你收集整理的Shiro 实现免密登陆的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: docker容器与宿主拷贝文件
- 下一篇: mybatisplus 一次性执行多条S