- 浏览: 1324931 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (896)
- spring4 (14)
- hibernate3 (26)
- spring2 (35)
- struts2 (55)
- struts1 (15)
- 设计模式 (15)
- java (172)
- mybatis3 (11)
- sql (17)
- mysql (13)
- jbpm (10)
- J2EE (45)
- tools (29)
- js (83)
- 数据结构 (13)
- Html (26)
- web (22)
- flex (33)
- Oracle (57)
- linux (49)
- 算法 (6)
- 其它 (12)
- easyui (1)
- bootstrap (13)
- xml (2)
- tomcat (1)
- redis (10)
- activemq (2)
- webservice (11)
- maven (2)
- springboot (1)
- ubuntu (1)
- python (14)
- rocketmq (1)
- springcloud (10)
- opencv (1)
最新评论
-
mike_eclipse:
Hashtable是线程不安全的吗?好像是线程安全的吧?
多线程之集合类 -
July01:
推荐用StratoIO打印控件,浏览器和系统的兼容性都很好,而 ...
lodop打印控件 -
xingcxb:
经过测试,假的,依旧会出现中文乱码!!!!store方法里面采 ...
java 读写Properties文件,不会出现中文乱码 -
tiger20111989:
...
Spring注解方式管理事务 -
zw7534313:
...
js 文字上下滚动 无间断循环显示
Shiro和JWT的区别
整合之前需要清楚Shiro和JWT的区别。
首先Shiro是一套安全认证框架,已经有了对token的相关封装。而JWT只是一种生成token的机制,需要我们自己编写相关的生成逻辑。
其次Shiro可以对权限进行管理,JWT在权限这部分也只能封装到token中
1、引入依赖
<!--Shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.5.3</version>
</dependency>
<!--JWT-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
和shiro相关:ShiroConfig、JWTFilter、MyRealm
2、JwtUtil
Jwt的自定义工具类,主要功能如下:
生成符合Jwt机制的token字符串
可以对token字符串进行校验
获取token中的用户信息
判断token是否过期
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 lombok.extern.slf4j.Slf4j;
import java.util.Date;
/**
@author: lhy
jwt工具,用来生成、校验token以及提取token中的信息
*/
@Slf4j
public class JwtUtil {
//指定一个token过期时间(毫秒)
private static final long EXPIRE_TIME = 7 * 24 * 60 * 60 * 1000; //7天
/**
生成token
*/
//注意这里的sercet不是密码,而是进行三件套(salt+MD5+1024Hash)处理密码后得到的凭证
//这里为什么要这么做,在controller中进行说明
public static String getJwtToken(String username, String secret) {
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
Algorithm algorithm = Algorithm.HMAC256(secret); //使用密钥进行哈希
// 附带username信息的token
return JWT.create()
.withClaim(“username”, username)
.withExpiresAt(date) //过期时间
.sign(algorithm); //签名算法
}
/**
校验token是否正确
*/
public static boolean verifyToken(String token, String username, String secret) {
try {
//根据密钥生成JWT效验器
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier verifier = JWT.require(algorithm)
.withClaim(“username”, username)
.build();
//效验TOKEN(其实也就是比较两个token是否相同)
DecodedJWT jwt = verifier.verify(token);
return true;
} catch (Exception exception) {
return false;
}
}
/**
在token中获取到username信息
*/
public static String getUsername(String token) {
try {
DecodedJWT jwt = JWT.decode(token);
return jwt.getClaim(“username”).asString();
} catch (JWTDecodeException e) {
return null;
}
}
public static boolean isExpire(String token){
DecodedJWT jwt = JWT.decode(token);
return jwt.getExpiresAt().getTime() < System.currentTimeMillis() ;
}
}
3、JwtToken
public class JwtToken implements AuthenticationToken {
private String token;
public JwtToken(String token) {
this.token = token;
}
@Override
public Object getPrincipal() {
return token;
}
@Override
public Object getCredentials() {
return token;
}
}
6、MyRealm
realm可以说是shiro两大功能:认证和授权的入口。可以自定义realm,对认证的方式进行自定义处理。重心先放在认证方法上,只要调用了subject.login(token)方法,就会进入到realm的doGetAuthenticationInfo内
public class MyRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
/**
* 限定这个realm只能处理JwtToken(不加的话会报错)
*/
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof JwtToken;
}
/**
* 授权(授权部分这里就省略了,先把重心放在认证上)
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//获取到用户名,查询用户权限
return null;
}
/**
* 认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) {
String token = (String) auth.getCredentials(); //JwtToken中重写了这个方法了
String username = JwtUtil.getUsername(token); // 获得username
//用户不存在(这个在登录时不会进入,只有在token校验时才有可能进入)
if(username == null)
throw new UnknownAccountException();
//根据用户名,查询数据库获取到正确的用户信息
User user = userService.getUserInfoByName(username);
//用户不存在(这个在登录时不会进入,只有在token校验时才有可能进入)
if(user == null)
throw new UnknownAccountException();
//密码错误(这里获取到password,就是3件套处理后的保存到数据库中的凭证,作为密钥)
if (! JwtUtil.verifyToken(token, username, user.getPassword())) {
throw new IncorrectCredentialsException();
}
//toke过期
if(JwtUtil.isExpire(token)){
throw new ExpiredCredentialsException();
}
return new SimpleAuthenticationInfo(user, token, getName());
}
}
5、JWTFilter
/**
* @author: lhy
* jwt过滤器,作为shiro的过滤器,对请求进行拦截并处理
跨域配置不在这里配了,我在另外的配置类进行配置了,这里把重心放在验证上
*/
@Slf4j
@Component
public class JwtFilter extends BasicHttpAuthenticationFilter{
/**
* 进行token的验证
*/
@Override
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
//在请求头中获取token
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String token = httpServletRequest.getHeader("Authorization"); //前端命名Authorization
//token不存在
if(token == null || "".equals(token)){
ResultTemplate<Object> res = new ResultTemplate<>();
res.setCode(StatusCode.UNLOGIN.getCode()).setMessage("无token,无权访问,请先登录");
out(response, res);
return false;
}
//token存在,进行验证
JwtToken jwtToken = new JwtToken(token);
try {
SecurityUtils.getSubject().login(jwtToken); //通过subject,提交给myRealm进行登录验证
return true;
} catch (ExpiredCredentialsException e){
ResultTemplate<Object> res = new ResultTemplate<>();
res.setCode(StatusCode.TOKENEXPIRED.getCode()).setMessage("token过期,请重新登录");
out(response,res);
e.printStackTrace();
return false;
} catch (ShiroException e){
// 其他情况抛出的异常统一处理,由于先前是登录进去的了,所以都可以看成是token被伪造造成的
ResultTemplate<Object> res = new ResultTemplate<>();
res.etCode(StatusCode.FAKETOKEN.getCode()).setMessage("token被伪造,无效token");
out(response,res);
e.printStackTrace();
return false;
}
}
/**
* json形式返回结果token验证失败信息,无需转发
*/
private void out(ServletResponse response, ResultTemplate<Object> res) throws IOException {
HttpServletResponse httpServletResponse = WebUtils.toHttp(response);
ObjectMapper mapper = new ObjectMapper();
String jsonRes = mapper.writeValueAsString(res);
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType("application/json; charset=utf-8");
httpServletResponse.getOutputStream().write(jsonRes.getBytes());
}
/**
* 过滤器拦截请求的入口方法
*/
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
try {
return executeLogin(request, response); //token验证
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
6、ShiroConfig
@Configuration
@Slf4j
public class ShiroConfig {
/**
* 由Spring管理 Shiro的生命周期
*/
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
/**
* 开启对 Shiro 注解的支持
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
@Bean
@DependsOn("lifecycleBeanPostProcessor")
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
// 强制使用cglib,防止重复代理和可能引起代理出错的问题
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
}
//创建ShiroFilter(用于拦截所有请求,对受限资源进行Shiro的认证和授权判断)
//Shiro提供了丰富的过滤器(anon等),不过在这里就需要加入我们自定义的JwtFilter了
@Bean("shiroFilter")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
// 添加自己的过滤器并且取名为jwt
Map<String, Filter> filterMap = new HashMap<>();
filterMap.put("jwt", new JwtFilter());
shiroFilterFactoryBean.setFilters(filterMap);
//配置系统的受限资源以及对应的过滤器
Map<String, String> ruleMap = new HashMap<>();
ruleMap.put("/user/login", "anon"); //登录路径、注册路径都需要放行不进行拦截
ruleMap.put("/user/register", "anon");
ruleMap.put("/**", "jwt"); // /**,一般放在最下,表示对所有资源起作用,使用JwtFilter
shiroFilterFactoryBean.setFilterChainDefinitionMap(ruleMap);
return shiroFilterFactoryBean;
}
//创建安全管理器(会自动设置到SecurityUtils中设置这个安全管理器)
//SecurityUtils可以用来获取subject对象
@Bean("securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(MyRealm realm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//给安全管理器设置realm
securityManager.setRealm(realm);
//关闭shiro的session(无状态的方式使用shiro)
DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
securityManager.setSubjectDAO(subjectDAO);
return securityManager;
}
//创建自定义Realm,注入到spring容器中
@Bean
public MyRealm getRealm(){
MyRealm realm = new MyRealm();
//修改凭证校验匹配器(处理加密),只有使用了UsernamePasswordToken并且有对password进行加密的才需要
// HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
// hashedCredentialsMatcher.setHashAlgorithmName("MD5");
// hashedCredentialsMatcher.setHashIterations(1024);
//
// realm.setCredentialsMatcher(hashedCredentialsMatcher);
return realm;
}
}
7、登录controller
@PostMapping("/login")
public ResultTemplate<String> register(@RequestBody User loginUser,
HttpServletRequest request){
//根据用户名获取正确用户信息
User user = userService.getUserInfoByName(username);
if(user == null)
return res.setCode(StatusCode.INVALIDUSER.getCode()).setMessage("无效用户,用户不存在");
//盐 + 输入的密码(注意不是用户的正确密码) + 1024次散列,作为token生成的密钥
String salt = user.getSalt();
Md5Hash md5Hash = new Md5Hash(password, salt, 1024);
//生成token字符串
String token = JwtUtil.getJwtToken(username, md5Hash.toHex());
}
整合之前需要清楚Shiro和JWT的区别。
首先Shiro是一套安全认证框架,已经有了对token的相关封装。而JWT只是一种生成token的机制,需要我们自己编写相关的生成逻辑。
其次Shiro可以对权限进行管理,JWT在权限这部分也只能封装到token中
1、引入依赖
<!--Shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.5.3</version>
</dependency>
<!--JWT-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
和shiro相关:ShiroConfig、JWTFilter、MyRealm
2、JwtUtil
Jwt的自定义工具类,主要功能如下:
生成符合Jwt机制的token字符串
可以对token字符串进行校验
获取token中的用户信息
判断token是否过期
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 lombok.extern.slf4j.Slf4j;
import java.util.Date;
/**
@author: lhy
jwt工具,用来生成、校验token以及提取token中的信息
*/
@Slf4j
public class JwtUtil {
//指定一个token过期时间(毫秒)
private static final long EXPIRE_TIME = 7 * 24 * 60 * 60 * 1000; //7天
/**
生成token
*/
//注意这里的sercet不是密码,而是进行三件套(salt+MD5+1024Hash)处理密码后得到的凭证
//这里为什么要这么做,在controller中进行说明
public static String getJwtToken(String username, String secret) {
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
Algorithm algorithm = Algorithm.HMAC256(secret); //使用密钥进行哈希
// 附带username信息的token
return JWT.create()
.withClaim(“username”, username)
.withExpiresAt(date) //过期时间
.sign(algorithm); //签名算法
}
/**
校验token是否正确
*/
public static boolean verifyToken(String token, String username, String secret) {
try {
//根据密钥生成JWT效验器
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier verifier = JWT.require(algorithm)
.withClaim(“username”, username)
.build();
//效验TOKEN(其实也就是比较两个token是否相同)
DecodedJWT jwt = verifier.verify(token);
return true;
} catch (Exception exception) {
return false;
}
}
/**
在token中获取到username信息
*/
public static String getUsername(String token) {
try {
DecodedJWT jwt = JWT.decode(token);
return jwt.getClaim(“username”).asString();
} catch (JWTDecodeException e) {
return null;
}
}
public static boolean isExpire(String token){
DecodedJWT jwt = JWT.decode(token);
return jwt.getExpiresAt().getTime() < System.currentTimeMillis() ;
}
}
3、JwtToken
public class JwtToken implements AuthenticationToken {
private String token;
public JwtToken(String token) {
this.token = token;
}
@Override
public Object getPrincipal() {
return token;
}
@Override
public Object getCredentials() {
return token;
}
}
6、MyRealm
realm可以说是shiro两大功能:认证和授权的入口。可以自定义realm,对认证的方式进行自定义处理。重心先放在认证方法上,只要调用了subject.login(token)方法,就会进入到realm的doGetAuthenticationInfo内
public class MyRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
/**
* 限定这个realm只能处理JwtToken(不加的话会报错)
*/
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof JwtToken;
}
/**
* 授权(授权部分这里就省略了,先把重心放在认证上)
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//获取到用户名,查询用户权限
return null;
}
/**
* 认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) {
String token = (String) auth.getCredentials(); //JwtToken中重写了这个方法了
String username = JwtUtil.getUsername(token); // 获得username
//用户不存在(这个在登录时不会进入,只有在token校验时才有可能进入)
if(username == null)
throw new UnknownAccountException();
//根据用户名,查询数据库获取到正确的用户信息
User user = userService.getUserInfoByName(username);
//用户不存在(这个在登录时不会进入,只有在token校验时才有可能进入)
if(user == null)
throw new UnknownAccountException();
//密码错误(这里获取到password,就是3件套处理后的保存到数据库中的凭证,作为密钥)
if (! JwtUtil.verifyToken(token, username, user.getPassword())) {
throw new IncorrectCredentialsException();
}
//toke过期
if(JwtUtil.isExpire(token)){
throw new ExpiredCredentialsException();
}
return new SimpleAuthenticationInfo(user, token, getName());
}
}
5、JWTFilter
/**
* @author: lhy
* jwt过滤器,作为shiro的过滤器,对请求进行拦截并处理
跨域配置不在这里配了,我在另外的配置类进行配置了,这里把重心放在验证上
*/
@Slf4j
@Component
public class JwtFilter extends BasicHttpAuthenticationFilter{
/**
* 进行token的验证
*/
@Override
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
//在请求头中获取token
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String token = httpServletRequest.getHeader("Authorization"); //前端命名Authorization
//token不存在
if(token == null || "".equals(token)){
ResultTemplate<Object> res = new ResultTemplate<>();
res.setCode(StatusCode.UNLOGIN.getCode()).setMessage("无token,无权访问,请先登录");
out(response, res);
return false;
}
//token存在,进行验证
JwtToken jwtToken = new JwtToken(token);
try {
SecurityUtils.getSubject().login(jwtToken); //通过subject,提交给myRealm进行登录验证
return true;
} catch (ExpiredCredentialsException e){
ResultTemplate<Object> res = new ResultTemplate<>();
res.setCode(StatusCode.TOKENEXPIRED.getCode()).setMessage("token过期,请重新登录");
out(response,res);
e.printStackTrace();
return false;
} catch (ShiroException e){
// 其他情况抛出的异常统一处理,由于先前是登录进去的了,所以都可以看成是token被伪造造成的
ResultTemplate<Object> res = new ResultTemplate<>();
res.etCode(StatusCode.FAKETOKEN.getCode()).setMessage("token被伪造,无效token");
out(response,res);
e.printStackTrace();
return false;
}
}
/**
* json形式返回结果token验证失败信息,无需转发
*/
private void out(ServletResponse response, ResultTemplate<Object> res) throws IOException {
HttpServletResponse httpServletResponse = WebUtils.toHttp(response);
ObjectMapper mapper = new ObjectMapper();
String jsonRes = mapper.writeValueAsString(res);
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType("application/json; charset=utf-8");
httpServletResponse.getOutputStream().write(jsonRes.getBytes());
}
/**
* 过滤器拦截请求的入口方法
*/
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
try {
return executeLogin(request, response); //token验证
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
6、ShiroConfig
@Configuration
@Slf4j
public class ShiroConfig {
/**
* 由Spring管理 Shiro的生命周期
*/
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
/**
* 开启对 Shiro 注解的支持
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
@Bean
@DependsOn("lifecycleBeanPostProcessor")
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
// 强制使用cglib,防止重复代理和可能引起代理出错的问题
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
}
//创建ShiroFilter(用于拦截所有请求,对受限资源进行Shiro的认证和授权判断)
//Shiro提供了丰富的过滤器(anon等),不过在这里就需要加入我们自定义的JwtFilter了
@Bean("shiroFilter")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
// 添加自己的过滤器并且取名为jwt
Map<String, Filter> filterMap = new HashMap<>();
filterMap.put("jwt", new JwtFilter());
shiroFilterFactoryBean.setFilters(filterMap);
//配置系统的受限资源以及对应的过滤器
Map<String, String> ruleMap = new HashMap<>();
ruleMap.put("/user/login", "anon"); //登录路径、注册路径都需要放行不进行拦截
ruleMap.put("/user/register", "anon");
ruleMap.put("/**", "jwt"); // /**,一般放在最下,表示对所有资源起作用,使用JwtFilter
shiroFilterFactoryBean.setFilterChainDefinitionMap(ruleMap);
return shiroFilterFactoryBean;
}
//创建安全管理器(会自动设置到SecurityUtils中设置这个安全管理器)
//SecurityUtils可以用来获取subject对象
@Bean("securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(MyRealm realm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//给安全管理器设置realm
securityManager.setRealm(realm);
//关闭shiro的session(无状态的方式使用shiro)
DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
securityManager.setSubjectDAO(subjectDAO);
return securityManager;
}
//创建自定义Realm,注入到spring容器中
@Bean
public MyRealm getRealm(){
MyRealm realm = new MyRealm();
//修改凭证校验匹配器(处理加密),只有使用了UsernamePasswordToken并且有对password进行加密的才需要
// HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
// hashedCredentialsMatcher.setHashAlgorithmName("MD5");
// hashedCredentialsMatcher.setHashIterations(1024);
//
// realm.setCredentialsMatcher(hashedCredentialsMatcher);
return realm;
}
}
7、登录controller
@PostMapping("/login")
public ResultTemplate<String> register(@RequestBody User loginUser,
HttpServletRequest request){
//根据用户名获取正确用户信息
User user = userService.getUserInfoByName(username);
if(user == null)
return res.setCode(StatusCode.INVALIDUSER.getCode()).setMessage("无效用户,用户不存在");
//盐 + 输入的密码(注意不是用户的正确密码) + 1024次散列,作为token生成的密钥
String salt = user.getSalt();
Md5Hash md5Hash = new Md5Hash(password, salt, 1024);
//生成token字符串
String token = JwtUtil.getJwtToken(username, md5Hash.toHex());
}
发表评论
-
web项目通过端口访问
2018-04-15 14:16 798发布到webapp下改一下web项目名为ROOT, ... -
tomcat 配置
2015-05-13 07:33 5501. 建立tomcat服务 A.在 ... -
eclipse 中自定义jsp模版
2011-05-17 22:16 2447首先随便打开一个jsp页,在网页中单击右键选择:prefer ... -
urlrewriter2.6在java中的应用 URL重写
2010-09-29 09:59 1541http://xiaopihai.iteye.com/blog ... -
内容管理系统CMS
2010-09-29 09:28 1118http://l530.spaces.live.com/blo ... -
web 网页中嵌套flash
2010-09-03 09:36 2122<object classid="clsid: ... -
web 开发一些组件
2010-08-26 11:24 1062http://www.live800.com/ Live ... -
web聊天 serverpush servlet实现
2010-07-01 09:11 2025这是个web聊天程序,很不错的,采用serverpush技术。 ... -
xml
2010-06-24 11:00 992Node.ELEMENT_NODE == 1 No ... -
远程上传 上传之前预览图片,可以验证类型,大小
2010-06-23 16:45 17351.upload_http.jsp: <style ... -
改变文件上传按钮样式 input button
2010-06-22 09:40 4792<style type="text/css&q ... -
天气插件
2010-06-17 09:45 928http://service.weather.com.cn/p ... -
WebBrowser 打印
2010-05-28 13:50 1507function hide(printId){ //pr ... -
lodop打印控件
2010-05-28 11:05 8071WEB免费打印控件推荐 http://fxz-2008.it ... -
css设置页面的打印样式及css用于不同媒体介质的设置
2010-05-27 16:42 4691这几天做东西涉及到 ... -
图片缓存 image
2010-01-22 14:31 1493<script language ="Java ... -
gif动画合成
2009-11-18 14:37 1242http://xxyy9090.blog.163.com/bl ... -
div +css 网页排版
2009-11-06 10:20 1166<!DOCTYPE HTML PUBLIC " ... -
fusionCharts
2009-11-02 17:17 1071f -
jasperreport
2009-10-16 09:28 1164http://maqianli.iteye.com/blog/ ...
相关推荐
最近在搞springboot的模块化开发,集成了shiro+jwt实现restful接口的token认证。 需新增测试表: CREATE TABLE `t_user` ( `user_id` int(11) unsigned zerofill NOT NULL AUTO_INCREMENT, `user_name` varchar(32...
总的来说,这个系统通过SpringBoot构建基础框架,利用Shiro进行权限控制,结合JWT实现无状态认证,借助Jedis提升性能,运用MybatisPlus简化数据库操作,实现了基于URL的权限管理。这种设计不仅提高了系统的安全性,...
总结起来,这个项目通过Shiro进行用户身份认证和权限管理,JWT提供了无状态的身份表示,SpringBoot作为核心框架集成各个组件,MySQL存储用户和权限数据,而Redis利用Jedis实现JWT的安全存储和快速访问。这样的设计既...
在现代Web应用开发中,安全认证与授权是至关重要的部分。...整个方案结合了Spring Boot的便捷性、Shiro的安全性、JWT的灵活性、Redis的高速缓存以及Mybatis的数据库操作,构建了一个完整的认证和授权解决方案。
而`Shiro`则是一个轻量级的安全管理框架,提供了用户认证、授权、会话管理和加密等功能。`JWT(JSON Web Token)`是一种高效的身份验证机制,可以在客户端和服务器之间安全地传递信息。本项目通过`SpringBoot`整合`...
本文档主要介绍了一个基于SpringBoot、JWT、Shiro和MybatisPlus实现的Restful后端脚手架,用于快速开发互联网项目。这个脚手架具备了一些关键特性,以提高开发效率和安全性。 首先,SpringBoot简化了传统的Spring...
通过以上步骤,我们可以构建一个完整的RBAC系统,其中Shiro处理权限控制,Jwt实现无状态认证,Redis提供高效的会话管理,而MyBatisPlus则简化了数据库操作。这样的系统不仅安全可靠,而且具有良好的扩展性和可维护性...
最后,我们可以使用 Shiro + JWT + SpringBoot 来实现身份验证和授权。 这篇文章主要介绍了 Shiro + JWT + SpringBoot 应用示例代码详解,通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴...
将JWT存储在Redis中,一方面可以减少数据库的压力,另一方面可以实现Token的自动刷新功能。当JWT接近过期时,我们可以检查Redis中是否存在对应的刷新令牌,如果存在,就生成一个新的JWT并返回给客户端,确保用户无...
SpringBoot2+MybatisPlus+SpringSecurity+jwt+redis+Vue的前后端分离的商城系统, 包含分类、sku、运费模板、素材库、小程序直播、拼团、砍价、商户管理、 秒杀、优惠券、积分、分销、会员、充值、多门店等功能,更...
"Shiro+SpringMVC+Redis+MySQL实现单点登录"是一个典型的系统安全架构,它整合了多个技术组件来构建一个高效、可靠的单点登录(Single Sign-On, SSO)解决方案。以下是关于这个主题的详细知识点: 1. **Apache ...
这个"springboot集成jwt和shiro实现前后端分离权限demo2"项目,旨在提供一个实际的案例,帮助开发者理解如何在Spring Boot应用中实现前后端分离的权限管理。通过学习和实践这个示例,你可以掌握JWT和Shiro的使用技巧...
基于JWT实现SSO单点登录流程图解 基于JWT实现SSO单点登录流程图解是指使用JSON Web Token(JWT)来实现单点登录(SSO)的机制。在这种机制中,用户只需要登录一次,就可以访问多个应用服务器上的资源,而不需要再次...
Shiro和JWT(JSON Web Tokens)用于用户认证和授权,确保系统的安全性,实现无状态化,符合RESTful API的设计原则。 【知识点详解】 1. **SpringBoot**:SpringBoot是Spring框架的一个衍生版本,简化了Spring应用...
# springboot+shiro+redis+jwt 基于Restful接口用户权限认证 ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信...
综合以上,这个项目利用Spring Boot作为基础框架,Shiro处理用户认证和授权,JWT提供安全的身份表示,Redis实现Token的存储和刷新,而Mybatis则负责与数据库交互。这样的设计确保了用户在不重新登录的情况下,能够在...
综上所述,这个项目提供了一个基于Java的后台系统框架,利用SpringBoot作为基础框架,Shiro进行用户安全控制,JWT处理用户认证,Vue.js全家桶构建现代化的前端界面,而Redis则增强了系统的性能和用户体验。...
在这个系统中,SpringBoot作为核心框架提供了快速开发的能力,Shiro是用于权限管理和认证的安全框架,JWT(Json Web Token)用于实现无状态的身份验证,Vue.js则作为前端框架负责用户界面的交互,而Redis则被用作...