目录
前言
一、shiro是什么?
二、使用步骤
1.引入依赖
2.代码讲解
源代码
前言
Shiro+SpringBoot+jwt集成小的Dome+源代码,源代码在最后
提示:以下是本篇文章正文内容,下面案例可供参考
一、shiro是什么?
Apache Shiro 是Java 的一个安全框架。Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE 环境,也可以用在JavaEE 环境。Shiro 可以帮助我们完成:认证、授权、加密、会话管理、与Web 集成、缓存等。
为什么用shiro?java领域中spring security(原名Acegi)也是一个开源的权限管理框架,但是spring security依赖spring运行,而shiro就相对独立,最主要是因为shiro使用简单、灵活,所以现在越来越多的用户选择shiro。
二、使用步骤
1.引入依赖
代码如下(示例):
org.apache.shiro shiro-spring1.3.2 org.apache.shiro shiro-core1.4.0 junit junit4.12
2.代码讲解
ShiroConfig
package com.hnchances.demo.shiro; import org.apache.shiro.mgt.DefaultSessionStorageEvaluator; import org.apache.shiro.mgt.DefaultSubjectDAO; import org.apache.shiro.spring.LifecycleBeanPostProcessor; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; import javax.servlet.Filter; import java.util.HashMap; import java.util.Map; @Configuration public class ShiroConfig { @Bean(name = "userRealm") public UserRealm userRealm(){ return new UserRealm(); } @Bean("securityManager") public DefaultWebSecurityManager getManager(@Qualifier("userRealm") UserRealm realm) { DefaultWebSecurityManager manager = new DefaultWebSecurityManager(); // 使用自己的realm manager.setRealm(realm); // // DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO(); // DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator(); // defaultSessionStorageEvaluator.setSessionStorageEnabled(false); // subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator); // manager.setSubjectDAO(subjectDAO); return manager; } @Bean("shiroFilter") public ShiroFilterFactoryBean factory(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); // 添加自己的过滤器并且取名为jwt MapfilterMap = new HashMap<>(); filterMap.put("jwt", new JWTFilter()); factoryBean.setFilters(filterMap); factoryBean.setSecurityManager(securityManager); Map filterRuleMap = new HashMap<>(); // filterRuleMap.put(" @Bean @DependsOn("lifecycleBeanPostProcessor") public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); // 强制使用cglib,防止重复代理和可能引起代理出错的问题 // https://zhuanlan.zhihu.com/p/29161098 defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); return defaultAdvisorAutoProxyCreator; } @Bean public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) { AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(securityManager); return advisor; } }
UserRealm
package com.hnchances.demo.shiro; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.hnchances.demo.entity.User; import com.hnchances.demo.service.UserService; import com.hnchances.demo.util.JWTUtils; import lombok.SneakyThrows; import org.apache.shiro.SecurityUtils; 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.stereotype.Service; @Service public class UserRealm extends AuthorizingRealm { @Autowired private UserService userService; @Override public boolean supports(AuthenticationToken token) { // TODO Auto-generated method stub return token instanceof JWTToken; } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); authorizationInfo.addStringPermission("user:add"); User activeUser = (User) SecurityUtils.getSubject().getPrincipal(); authorizationInfo.addStringPermission(activeUser.getIdentity()+""); // // if(activeUser.getUser().getType()==0){ // authorizationInfo.addStringPermission("*:*"); // }else { // Listpermissions = new ArrayList<>(activeUser.getPermissions()); // List roleList = activeUser.getRoles(); // //授权角色 // if (!CollectionUtils.isEmpty(roleList)) { // for (Role role : roleList) { // authorizationInfo.addRole(role.getRoleName()); // } // } // //授权权限 // if (!CollectionUtils.isEmpty(permissions)) { // for (String permission : permissions) { // if (permission != null && !"".equals(permission)) { // authorizationInfo.addStringPermission(permission); // } // } // } // } return authorizationInfo; } @SneakyThrows @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException { String token = (String) auth.getCredentials(); // 解密获得username,用于和数据库进行对比 String username = JWTUtils.getUsername(token); if (username == null) { throw new AuthenticationException(" token错误,请重新登入!"); } QueryWrapper queryWrapper = new QueryWrapper(); queryWrapper.eq("userName",username); User userBean = userService.getOne(queryWrapper); if (userBean == null) { throw new AccountException("账号不存在!"); } if(JWTUtils.isExpire(token)){ throw new AuthenticationException(" token过期,请重新登入!"); } if (! JWTUtils.verify(token, username, userBean.getPassWord())) { throw new CredentialsException("密码错误!"); } // //如果验证通过,获取用户的角色 // List roles= userService.findRolesById(userBean.getId()); // //查询用户的所有菜单(包括了菜单和按钮) // List
jwtUtil
package com.hnchances.demo.util; import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTDecodeException; import com.auth0.jwt.interfaces.DecodedJWT; import java.io.UnsupportedEncodingException; import java.util.Date; public class JWTUtils { private static final long EXPIRE_TIME = 6*60*60*1000; public static boolean verify(String token, String username, String secret) { try { Algorithm algorithm = Algorithm.HMAC256(secret); JWTVerifier verifier = JWT.require(algorithm) .withClaim("username", username) .build(); DecodedJWT jwt = verifier.verify(token); return true; } catch (Exception exception) { return false; } } public static String getUsername(String token) { try { DecodedJWT jwt = JWT.decode(token); return jwt.getClaim("username").asString(); } catch (JWTDecodeException e) { return null; } } public static String sign(String username, String secret) { try { Date date = new Date(System.currentTimeMillis()+EXPIRE_TIME); Algorithm algorithm = Algorithm.HMAC256(secret); // 附带username信息 return JWT.create() .withClaim("username", username) .withExpiresAt(date) .sign(algorithm); } catch (UnsupportedEncodingException e) { return null; } } public static boolean isExpire(String token){ DecodedJWT jwt = JWT.decode(token); return System.currentTimeMillis()>jwt.getExpiresAt().getTime(); } }
UserController
@ApiOperation(value = "用户登录") @PostMapping("/login") public R login(String username,String password){ Subject subject = SecurityUtils.getSubject(); String token = JWTUtils.sign(username, password); JWTToken jwtToken = new JWTToken(token); try{ subject.login(jwtToken); return R.success("登录成功"); }catch (UnknownAccountException e){ return R.success("用户名错误"); } catch (IncorrectCredentialsException e){ return R.success("密码错误"); } }
源代码
源代码demo
StudentManagementSystemdemo: java岗位测试
源代码demo
StudentManagementSystemdemo: java岗位测试