大致内容 用到下面五个类
![在这里插入图片描述](https://img-blog.csdnimg.cn/fa462f0092d443d696695304fd51a9ef.png)
CustomRealm
public class CustomRealm extends AuthorizingRealm {
@Resource
private UserService userService;
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof JwtToken;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
return simpleAuthorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String token = (String) authenticationToken.getCredentials();
Assert.isTrue(!JwtUtil.isExpire(token),"token失效,请重新登录");
String username = JwtUtil.getUsername(token);
Assert.notNull(username,"用户不存在");
User user = userService.findUserByUserName(username);
Assert.isTrue(JwtUtil.verifyToken(token,username,user.getPassword()),"密码不正确");
return new SimpleAuthenticationInfo(user, token, this.getName());
}
}
JwtFilter
@Log4j2
public class JwtFilter extends BasicHttpAuthenticationFilter {
private static final String TOKEN = "Authentication";
private AntPathMatcher pathMatcher = new AntPathMatcher();
private void ResponseOut(ServletResponse response, Map<String, Object> map) throws IOException {
String json = JsonUtil.toJSONString(map);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().println(json);
}
@Override
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String token = httpServletRequest.getHeader(TOKEN);
if (StringUtils.isBlank(token)) {
HashMap<String, Object> hashMap = new HashMap<>(2);
hashMap.put("mag","无token,无权访问,请先登录");
ResponseOut(response,hashMap);
return false;
}
JwtToken jwtToken = new JwtToken(token);
try {
SecurityUtils.getSubject().login(jwtToken);
return true;
} catch (ExpiredCredentialsException e) {
HashMap<String, Object> hashMap = new HashMap<>(2);
hashMap.put("mag","token过期,请重新登录");
ResponseOut(response,hashMap);
log.error("token过期,请重新登录:{}",ExceptionUtil.stacktraceToString(e));
return false;
} catch (ShiroException e){
HashMap<String, Object> hashMap = new HashMap<>(2);
hashMap.put("mag","token无效");
ResponseOut(response,hashMap);
log.error("token无效:{}",ExceptionUtil.stacktraceToString(e));
return false;
}
}
@SneakyThrows
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
boolean result = false;
result = executeLogin(request,response);
return result;
}
@Override
protected boolean isLoginAttempt(ServletRequest request,ServletResponse response){
boolean result = false;
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
if(httpServletRequest.getHeader(TOKEN)!=null){
result = true;
}
return result;
}
@Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setHeader("Access-control-Allow-Origin", "*");
httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
boolean result = false;
if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
httpServletResponse.setStatus(HttpStatus.OK.value());
} else {
result = super.preHandle(request, response);
}
return result;
}
}
JwtToken
@Data
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;
}
}
JwtUtil
@Slf4j
public class JwtUtil {
private static final String SING = "!@#$%^&*A1D2FRT5";
private static final long EXPIRE_TIME= 7200 * 1000;
public static String getUsername(String token){
String result = null;
try{
DecodedJWT jwt = JWT.decode(token);
result = jwt.getClaim("username").asString();
}catch (JWTDecodeException e){
log.error("error {}",e.getMessage());
}
return result;
}
public static Long getUserId(String token){
Long userId = null;
try{
DecodedJWT jwt = JWT.decode(token);
userId = jwt.getClaim("userId").asLong();
}catch (JWTDecodeException e){
log.error("error {}",e.getMessage());
}
return userId;
}
public static String getJwtToken(String username,Long userId,String password){
try{
return JWT.create()
.withClaim("userId",userId)
.withClaim("username",username)
.withExpiresAt(new Date(System.currentTimeMillis()+EXPIRE_TIME))
.sign(Algorithm.HMAC256(ObjectUtil.isNull(password)?SING:password));
}catch (Exception e){
log.error("error:{}", ExceptionUtil.stacktraceToString(e));
return null;
}
}
public static boolean verifyToken(String token,String username, String password) {
try {
Algorithm algorithm = Algorithm.HMAC256(StrUtil.isBlank(password) ? SING : password);
JWT.require(algorithm)
.withClaim("username", username)
.build()
.verify(token);
return true;
} catch (Exception e) {
log.error("error:{}", ExceptionUtil.stacktraceToString(e));
}
return false;
}
public static boolean isExpire(String token){
DecodedJWT jwt = JWT.decode(token);
return jwt.getExpiresAt().getTime() < DateUtil.current();
}
}
ShiroConfig
@Configuration
public class ShiroConfig {
@Bean
public CustomRealm customRealm(){
return new CustomRealm();
}
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(customRealm());
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
LinkedHashMap<String, Filter> filters = new LinkedHashMap<>();
filters.put("jwt",new JwtFilter());
shiroFilterFactoryBean.setFilters(filters);
LinkedHashMap<String,String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/api/sys/user/login", "anon");
filterChainDefinitionMap.put("/api/**","jwt");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}
测试
@Data
public class User {
private Long id;
private String username;
private String password;
}
@Slf4j
@RestController
@RequestMapping("/api/sys/user")
public class UserController {
@Resource
private UserService userService;
@GetMapping("/login")
public Map<String,Object> login(String userName, String passWord) {
return userService.login(userName,passWord);
}
@GetMapping("/page")
public Map<String,Object> list() {
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("username","admin");
return hashMap;
}
}
public interface UserService {
User findUserByUserName(String username);
Map<String, Object> login(String userName, String passWord);
}
@Service
public class UserServiceImpl implements UserService {
@Override
public User findUserByUserName(String username) {
if ("admin".equals(username)) {
User user = new User();
user.setUsername("admin");
user.setPassword("123456");
user.setId(Long.valueOf(123456789));
return user;
}
return null;
}
@Override
public Map<String, Object> login(String userName, String passWord) {
if ("admin".equals(userName)) {
User user = new User();
user.setUsername("admin");
user.setPassword("123456");
user.setId(Long.valueOf(123456789));
String token = JwtUtil.getJwtToken(user.getUsername(), user.getId(), user.getPassword());
JwtToken jwtToken = new JwtToken(token);
Map<String, Object> hashMap = new HashMap<>();
hashMap.put("token",jwtToken.getToken());
return hashMap;
}
return null;
}
}