首页 > 网站 > 帮助中心 > 正文

Spring boot整合shiro+jwt实现前后端分离

2024-07-09 22:42:40
字体:
来源:转载
供稿:网友

本文实例为大家分享了Spring boot整合shiro+jwt实现前后端分离的具体代码,供大家参考,具体内容如下

这里内容很少很多都为贴的代码,具体内容我经过了看源码和帖子加了注释。帖子就没用太多的内容

先下载shiro和jwt的jar包

<!-- shiro包 --><dependency>  <groupId>org.apache.shiro</groupId>  <artifactId>shiro-spring</artifactId>  <version>1.4.0</version></dependency><dependency>  <groupId>org.apache.shiro</groupId>  <artifactId>shiro-ehcache</artifactId>  <version>1.4.0</version></dependency><!--JWT依赖--><!--JWT--><dependency>  <groupId>com.auth0</groupId>  <artifactId>java-jwt</artifactId>  <version>3.4.0</version></dependency><!--JJWT--><dependency>   <groupId>io.jsonwebtoken</groupId>   <artifactId>jjwt</artifactId>   <version>0.9.0</version></dependency>

创建shiro的自定义的Realm

代码如下:

package com.serverprovider.config.shiro.userRealm;  import com.spring.common.auto.autoUser.AutoUserModel;import com.spring.common.auto.autoUser.extend.AutoModelExtend;import com.serverprovider.config.shiro.jwt.JWTCredentialsMatcher;import com.serverprovider.config.shiro.jwt.JwtToken;import com.serverprovider.service.loginService.LoginServiceImpl;import com.util.Redis.RedisUtil;import com.util.ReturnUtil.SecretKey;import com.util.encryption.JWTDecodeUtil;import io.jsonwebtoken.Claims;import org.apache.log4j.Logger;import org.apache.shiro.authc.*;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.ExceptionHandler; import java.util.HashSet;import java.util.List;import java.util.Set; public class UserRealm extends AuthorizingRealm {   private Logger logger = Logger.getLogger(UserRealm.class);    @Autowired private LoginServiceImpl loginService;    public UserRealm(){    //这里使用我们自定义的Matcher验证接口    this.setCredentialsMatcher(new JWTCredentialsMatcher());  }   /**   * 必须重写此方法,不然Shiro会报错   */  @Override  public boolean supports(AuthenticationToken token) {    return token instanceof JwtToken;  }   /**   * shiro 身份验证   * @param token   * @return boolean   * @throws AuthenticationException 抛出的异常将有统一的异常处理返回给前端   *   */  @Override  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)throws AuthenticationException {    /**     * AuthenticationToken     * JwtToken重写了AuthenticationToken接口 并创建了一个接口token的变量     *  因为在filter我们将token存入了JwtToken的token变量中     *  所以这里直接getToken()就可以获取前端传递的token值     */      String JWTtoken = ((JwtToken) token).getToken();    /**     * Claims对象它最终是一个JSON格式的对象,任何值都可以添加到其中     * token解密 转换成Claims对象     */       Claims claims = JWTDecodeUtil.parseJWT(JWTtoken, SecretKey.JWTKey);          /**     *  根据JwtUtil加密方法加入的参数获取数据     *  查询数据库获得对象     *  如为空:抛出异常     *  如验证失败抛出 AuthorizationException     */      String username = claims.getSubject();      String password = (String) claims.get("password");      AutoModelExtend principal = loginService.selectLoginModel(username,password);      return new SimpleAuthenticationInfo(principal, JWTtoken,"userRealm");  }    @Override  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {    SimpleAuthorizationInfo info = null;    /**     * PrincipalCollection对象     * 文档里面描述:返回从指定的Realm 仅作为Collection 返回的单个Subject的对象,如果没有来自该领域的任何对象,则返回空的Collection。     * 在登录接口放入权限注解返回的错误信息:Subject.login(AuthenticationToken)或SecurityManager启用'Remember Me'功能后成功自动获取这些标识主体     * 当调用Subject.login()方法成功后 PrincipalCollection会自动获得该对象 如没有认证过或认证失败则返回空的Collection并抛出异常     * getPrimaryPrincipal():返回在应用程序范围内使用的主要对象,以唯一标识拥有帐户。     */    Object principal = principals.getPrimaryPrincipal();    /**     * 得到身份对象     * 查询该用户的权限信息     */    AutoUserModel user = (AutoUserModel) principal;    List<String> roleModels = loginService.selectRoleDetails(user.getId());    try {    /**     * 创建一个Set,来放置用户拥有的权限     * 创建 SimpleAuthorizationInfo, 并将办好权限列表的Set放入.     */    Set<String> rolesSet = new HashSet();    for (String role : roleModels) {      rolesSet.add(role);    }    info = new SimpleAuthorizationInfo();    info.setStringPermissions(rolesSet);  // 放入权限信息  }catch (Exception e){    throw new AuthenticationException("授权失败!");  }    return info;  }}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表