武进网站建设哪家好,职业培训网,学校网站怎么做的好坏,好看的学校网站模板需求#xff1a;对接第三方登陆#xff0c;实现绕过原有Shiro认证登陆。 文章目录一、实现思路1. 现状分析2. 用户来源3. 所属范围二、实现方案2.1. 自定义登录认证规则2.2. Shiro认证枚举2.3. 密码和非密码登录2.4. 规则配置2.5. 自定义Realm2.6. 案例使用一、实现思路
1. … 需求对接第三方登陆实现绕过原有Shiro认证登陆。 文章目录一、实现思路1. 现状分析2. 用户来源3. 所属范围二、实现方案2.1. 自定义登录认证规则2.2. Shiro认证枚举2.3. 密码和非密码登录2.4. 规则配置2.5. 自定义Realm2.6. 案例使用一、实现思路
1. 现状分析
系统权框架默认使用Shiro 认证授权机制
2. 用户来源
从统一认证平台登录跳转过来的用户
3. 所属范围
登录限制由统一认证平台去做但是跳转过来的用户仍然走您本系统的登录流程只是走本系统的登录流程时想跳过Shiro 对用户密码的校验校验所属范围为Shiro 认证机制其他功能照旧
二、实现方案
2.1. 自定义登录认证规则
package com.gblfy.config.skipshiro;import com.gblfy.config.skipshiro.enums.ShiroApproveLoginType;
import org.apache.shiro.authc.UsernamePasswordToken;/*** 自定义token 实现免密和密码登录* p* 1.账号密码登陆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;}/*** 账号密码登录*/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认证枚举
package com.gblfy.config.skipshiro.enums;/*** Shiro认证枚举* author gblfy* date 2021-10-22*/
public enum ShiroApproveLoginType {/** 密码登录 */PASSWORD(PASSWORD),/** 密码登录 */NOPASSWD(NOPASSWORD);/** 状态值 */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;/*** 自定义登录认证方案* p* 1.免密登录不加密* 2.密码登录md5加密* /p** author gblfy* date 2021-10-22*/
public class EasyCredentialsMatch extends HashedCredentialsMatcher {/*** 重写方法* 区分 密码和非密码登录* 此次无需记录登录次数 详情看SysPasswordService*/Overridepublic boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {EasyUsernameToken easyUsernameToken (EasyUsernameToken) token;//免密登录,不验证密码if (ShiroApproveLoginType.NOPASSWD.equals(easyUsernameToken.getType())) {return true;}//密码登录Object tokenHashedCredentials hashProvidedCredentials(token, info);Object accountCredentials getCredentials(info);return equals(tokenHashedCredentials, accountCredentials);}
}
2.4. 规则配置 Beanpublic EasyCredentialsMatch customCredentialsMatch() {EasyCredentialsMatch customCredentialsMatch new EasyCredentialsMatch();customCredentialsMatch.setHashAlgorithmName(md5);customCredentialsMatch.setHashIterations(3);customCredentialsMatch.setStoredCredentialsHexEncoded(true);return customCredentialsMatch;}2.5. 自定义Realm
权限认证 保持默认修改登录认证
public class UserRealm extends AuthorizingRealm {/*** 权限认证 */Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//权限认证 代码省略}/*** 登录认证*/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(对用户[ username ]进行登录验证..验证未通过{}, 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 用户或密码错误;if (StringUtils.isNotEmpty(e.getMessage())) {msg e.getMessage();}return error(msg);}}