哪个网站可以做puzzle,自定义wordpress,长沙网站建设建,江苏品牌网站建设最近和别的软件集成项目#xff0c;需要提供给别人接口来进行数据传输#xff0c;发现给他token后并不能访问我的接口#xff0c;拿postman试了下还真是不行。检查代码发现项目的shiro配置是通过session会话来校验信息的 #xff0c;我之前一直是前后端自己写#xff0c;用…最近和别的软件集成项目需要提供给别人接口来进行数据传输发现给他token后并不能访问我的接口拿postman试了下还真是不行。检查代码发现项目的shiro配置是通过session会话来校验信息的 我之前一直是前后端自己写用浏览器来调试的程序所以没发现这个问题。 浏览器请求头的cookie带着JESSIONID是可以正常访问接口的
那要和别的项目集成他那边又不是通过浏览器咋办呢我这边改造吧兼容token和session不就行了下面直接贴改造后的完整代码。
pom加依赖 dependencygroupIdorg.crazycake/groupIdartifactIdshiro-redis/artifactIdversion2.4.2.1-RELEASE/version/dependencydependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-all/artifactIdversion1.3.2/version/dependencydependencygroupIdcom.auth0/groupIdartifactIdjava-jwt/artifactIdversion3.2.0/version/dependency1.JwtToken重写token类型
package com.mes.common.token;import com.mes.module.user.dto.SysUserDto;
import lombok.Data;
import org.apache.shiro.authc.HostAuthenticationToken;
import org.apache.shiro.authc.RememberMeAuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;Data
public class JwtToken implements HostAuthenticationToken, RememberMeAuthenticationToken {private String token;private char[] password;private boolean rememberMe false;private String host;public JwtToken(String token){this.token token;}Overridepublic String getHost() {return null;}Overridepublic boolean isRememberMe() {return false;}Overridepublic Object getPrincipal() {return token;}Overridepublic Object getCredentials() {return token;}
}
2.自定义过滤器 JwtFilter
package com.mes.common.shiro;import com.alibaba.fastjson.JSON;
import com.auth0.jwt.interfaces.Claim;
import com.mes.common.token.JwtToken;
import com.mes.common.utils.JwtUtils;
import com.mes.common.utils.Result;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;/*** Description 自定义过滤器* Date 2021/8/18**/
public class JwtFilter extends AuthenticatingFilter {private static final Logger log LoggerFactory.getLogger(JwtFilter.class);Overrideprotected AuthenticationToken createToken(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {HttpServletRequest request (HttpServletRequest) servletRequest;String token request.getHeader(token);if (token null){return null;}return new JwtToken(token);}/*** 拦截校验 没有登录的情况下会走此方法* param servletRequest* param servletResponse* return* throws Exception*/Overrideprotected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {HttpServletRequest request (HttpServletRequest) servletRequest;HttpServletResponse response (HttpServletResponse) servletResponse;String token request.getHeader(token);response.setContentType(application/json;charsetutf-8);response.setHeader(Access-Control-Allow-Credentials, true);response.setHeader(Access-control-Allow-Origin, request.getHeader(Origin));response.setHeader(Access-Control-Allow-Methods, GET,PUT,DELETE,UPDATE,OPTIONS);response.setHeader(Access-Control-Allow-Headers, request.getHeader(Access-Control-Request-Headers));Subject subject getSubject(servletRequest,servletResponse);if (!subject.isAuthenticated()){// 未登录PrintWriter writer response.getWriter();writer.print(JSON.toJSONString(new Result().setCode(402).setMsg(请先登录)));return false;}if (StringUtils.isEmpty(token)){PrintWriter writer response.getWriter();writer.print(JSON.toJSONString(new Result().setCode(402).setMsg(请先登录)));return false;}else {// 校验jwttry {MapString, Claim claimMap JwtUtils.verifyToken(token);} catch (Exception e) {e.printStackTrace();PrintWriter writer response.getWriter();writer.write(JSON.toJSONString(new Result().setCode(402).setMsg(登录失效请重新登录)));return false;}return executeLogin(servletRequest, servletResponse);}}Overrideprotected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {HttpServletResponse httpServletResponse (HttpServletResponse) response;Throwable throwable e.getCause() null ? e : e.getCause();Result result new Result().err().setMsg(e.getMessage());String json JSON.toJSONString(result);try {httpServletResponse.getWriter().print(json);} catch (IOException ioException) {}return false;}/*** 跨域支持* param servletRequest* param response* return* throws Exception*/Overrideprotected boolean preHandle(ServletRequest servletRequest, ServletResponse response) throws Exception {HttpServletRequest httpRequest WebUtils.toHttp(servletRequest);HttpServletResponse httpResponse WebUtils.toHttp(response);if (httpRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {httpResponse.setHeader(Access-Control-Allow-Credentials, true);httpResponse.setHeader(Access-control-Allow-Origin, httpRequest.getHeader(Origin));httpResponse.setHeader(Access-Control-Allow-Methods, GET,PUT,DELETE,UPDATE,OPTIONS);httpResponse.setHeader(Access-Control-Allow-Headers, httpRequest.getHeader(Access-Control-Request-Headers));System.out.println(httpRequest.getHeader(Origin));System.out.println(httpRequest.getMethod());System.out.println(httpRequest.getHeader(Access-Control-Request-Headers));httpResponse.setStatus(HttpStatus.OK.value());return false;}HttpServletRequest request (HttpServletRequest) servletRequest;String token request.getHeader(token);if (token ! null) {try {
// MapString, Claim claimMap JwtUtils.verifyToken(token);
// String authToken claimMap.get(token).asString();JwtToken jwtToken new JwtToken(token);Subject subject SecurityUtils.getSubject();subject.login(jwtToken);return true;} catch (Exception e) {e.printStackTrace();log.error(token失效请重新登录);response.getWriter().print(JSON.toJSONString(new Result().setCode(402).setMsg(token失效请重新登录)));}}return false;}/* protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {HttpServletRequest httpRequest WebUtils.toHttp(request);HttpServletResponse httpResponse WebUtils.toHttp(response);if (httpRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {httpResponse.setHeader(Access-Control-Allow-Credentials, true);httpResponse.setHeader(Access-control-Allow-Origin, httpRequest.getHeader(Origin));httpResponse.setHeader(Access-Control-Allow-Methods, GET,PUT,DELETE,UPDATE,OPTIONS);httpResponse.setHeader(Access-Control-Allow-Headers, httpRequest.getHeader(Access-Control-Request-Headers));System.out.println(httpRequest.getHeader(Origin));System.out.println(httpRequest.getMethod());System.out.println(httpRequest.getHeader(Access-Control-Request-Headers));httpResponse.setStatus(HttpStatus.OK.value());return false;}return super.preHandle(request, response);}*/}
3.配置过滤器 ShiroFilterRegisterConfig
package com.mes.common.config;import com.mes.common.shiro.JwtFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** Description TODO* Date 2021/8/19**/
Configuration
public class ShiroFilterRegisterConfig {Beanpublic FilterRegistrationBean shiroLoginFilteRegistration(JwtFilter filter) {FilterRegistrationBean registration new FilterRegistrationBean(filter);registration.setEnabled(false);return registration;}
}
4. shiroConfig
package com.mes.common.config;
import com.baomidou.mybatisplus.extension.api.R; import com.mes.common.constant.ExpTime; import com.mes.common.realm.MyRealm; import com.mes.common.shiro.JwtFilter; import com.mes.common.shiro.MyCredentialsMatcher; import org.apache.shiro.session.mgt.SessionManager; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; import org.crazycake.shiro.RedisCacheManager; import org.crazycake.shiro.RedisManager; import org.crazycake.shiro.RedisSessionDAO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map;
/**
Description shiro配置Date 2021/8/18 **/ Configuration public class ShiroConfig { Autowired private MyRealm myRealm; Autowired private MyCredentialsMatcher myCredentialsMatcher; Value(“ s p r i n g . r e d i s . h o s t ) p r i v a t e S t r i n g r e d i s H o s t ; V a l u e ( {spring.redis.host}) private String redisHost; Value( spring.redis.host)privateStringredisHost;Value({spring.redis.port}”) private Integer redisPort; Value(“${spring.redis.timeout}”) private Integer redisTimeout;
// Bean // public DefaultWebSessionManager sessionManager(Value(“${globalSessionTimeout:3600}”) long globalSessionTimeout, RedisManager c){ // DefaultWebSessionManager sessionManager new DefaultWebSessionManager(); // sessionManager.setSessionValidationSchedulerEnabled(true); // sessionManager.setSessionIdUrlRewritingEnabled(false); // sessionManager.setSessionValidationInterval(globalSessionTimeout * 1000); // sessionManager.setGlobalSessionTimeout(globalSessionTimeout * 1000); // sessionManager.setSessionDAO(redisSessionDAO©); // return sessionManager; // } // ConfigurationProperties(prefix“spring.redis”) // Bean // public RedisManager redisManager() { // return new RedisManager(); // } // Bean // public RedisSessionDAO redisSessionDAO(RedisManager redisManager) { // RedisSessionDAO redisSessionDAO new RedisSessionDAO(); // redisSessionDAO.setRedisManager(redisManager); // return redisSessionDAO; // }
// Bean // public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator(){ // // DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreatornew DefaultAdvisorAutoProxyCreator(); // defaultAdvisorAutoProxyCreator.setUsePrefix(true); // // return defaultAdvisorAutoProxyCreator; // }
Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(SessionManager sessionManager, RedisCacheManager redisCacheManager){DefaultWebSecurityManager defaultWebSecurityManager new DefaultWebSecurityManager();myRealm.setCredentialsMatcher(myCredentialsMatcher);defaultWebSecurityManager.setRealm(myRealm);// defaultWebSecurityManager.setSessionManager(sessionManager); defaultWebSecurityManager.setCacheManager(redisCacheManager); return defaultWebSecurityManager; }
Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager,JwtFilter jwtFilter){ShiroFilterFactoryBean shiroFilterFactoryBean new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);// JwtFilter jwtFilter new JwtFilter(); MapString, Filter filterMap new HashMap(); filterMap.put(“jwt”,jwtFilter); shiroFilterFactoryBean.setFilters(filterMap); MapString,String map new LinkedHashMap(); map.put(“/sys/user/login”,“anon”); map.put(“/swagger-ui.html**”, “anon”); map.put(“/v2/api-docs”, “anon”); map.put(“/swagger-resources/“, “anon”); map.put(”/webjars/”, “anon”); map.put(“/img/“,“anon”); map.put(”/fastdfs/”,“anon”); map.put(“/**”,“jwt”); //取消就不会拦截 shiroFilterFactoryBean.setFilterChainDefinitionMap(map); // shiroFilterFactoryBean.setLoginUrl(“http://192.168.18.17:3000”); return shiroFilterFactoryBean; }
Bean
public JwtFilter getJwtFilter(){return new JwtFilter();
}/*** 配置shiro redisManager* 使用的是shiro-redis开源插件* return*/
Bean
public RedisManager redisManager() {RedisManager redisManager new RedisManager();redisManager.setHost(redisHost);redisManager.setPort(redisPort);redisManager.setExpire(Math.toIntExact(ExpTime.expTime));// 配置缓存过期时间redisManager.setTimeout(redisTimeout);return redisManager;
}
Bean
public RedisSessionDAO redisSessionDAO(RedisManager redisManager) {// RedisSessionDAO redisSessionDAO new RedisSessionDAO(); RedisSessionDAO redisSessionDAO new RedisSessionDAO(); redisSessionDAO.setRedisManager(redisManager); return redisSessionDAO; } /** * shiro session的管理 */ Bean public DefaultWebSessionManager redisSessionManager(RedisSessionDAO redisSessionDAO) { DefaultWebSessionManager sessionManager new DefaultWebSessionManager(); sessionManager.setSessionDAO(redisSessionDAO); return sessionManager; } Bean public RedisCacheManager redisCacheManager(RedisManager redisManager) { RedisCacheManager redisCacheManager new RedisCacheManager(); redisCacheManager.setRedisManager(redisManager); return redisCacheManager; }
// Bean // public FilterRegistrationBean shiroLoginFilteRegistration(JwtFilter filter) { // FilterRegistrationBean registration new FilterRegistrationBean(filter); // registration.setEnabled(false); // return registration; // }
}
在这里插入代码片5.自定义认证逻辑 MyRealm
package com.mes.common.realm;
import com.auth0.jwt.interfaces.Claim; import com.mes.common.token.JwtToken; import com.mes.common.utils.JwtUtils; import com.mes.module.user.dto.SysUserDto; import com.mes.module.user.service.SysUserService; import lombok.SneakyThrows; 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.Component;
import java.util.HashMap; import java.util.Map;
/** Description 授权 Date 2021/8/18 **/ Component public class MyRealm extends AuthorizingRealm { Autowired private SysUserService sysUserService; Override public boolean supports(AuthenticationToken token) { return token instanceof JwtToken; } Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { String username (String) principalCollection.iterator().next(); SimpleAuthorizationInfo info new SimpleAuthorizationInfo(); return info; } SneakyThrows Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { JwtToken jwtToken (JwtToken) authenticationToken; String token (String) jwtToken.getPrincipal(); MapString, Claim claimMap JwtUtils.verifyToken(token); String username claimMap.get(“name”).asString(); MapString,Object params new HashMap(); params.put(“username”, username); SysUserDto userDto sysUserService.getOne(params); if (userDto null){ return null; }
// return new SimpleAuthenticationInfo(userDto,userDto.getPassword(),getName()); return new SimpleAuthenticationInfo(userDto,jwtToken,getName()); } }
6.密码验证器
package com.mes.common.shiro;import com.mes.common.token.JwtToken;
import com.mes.common.utils.CommonsUtils;
import com.mes.module.user.dto.SysUserDto;
import com.mes.module.user.service.SysUserService;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.HashMap;
import java.util.Map;/*** Description 密码验证器* Date 2021/8/18**/
Component
public class MyCredentialsMatcher extends SimpleCredentialsMatcher {Autowiredprivate SysUserService sysUserService;Overridepublic boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {JwtToken jwtToken (JwtToken) token;if (jwtToken.getPassword() null){return true;}String inPassword new String(jwtToken.getPassword());SysUserDto dto (SysUserDto) info.getPrincipals();String username dto.getUsername();String dbPassword String.valueOf(info.getCredentials());MapString,Object params new HashMap();params.put(username,username);SysUserDto dbUser sysUserService.getOne(params);String salt dbUser.getSalt();if (CommonsUtils.encryptPassword(inPassword,salt).equals(dbPassword)){return true;}else {return false;}}
}