美文网首页
spring boot security jwt

spring boot security jwt

作者: Feng_Sir | 来源:发表于2017-07-05 14:33 被阅读0次
image.png
<dependencies>
     <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
        </dependency>
        <!-- jwt  json web token -->
        <dependency>
          <groupId>io.jsonwebtoken</groupId>
          <artifactId>jjwt</artifactId>
          <version>0.7.0</version>
        </dependency>
        <!-- spring boot security -->
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
            <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
<dependencies>
package cn.etstone.evm.configuration.security;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import cn.etstone.evm.configuration.jwt.JWTAuthenticationFilter;
import cn.etstone.evm.configuration.jwt.JWTLoginFilter;


@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) // 允许进入页面方法前检验
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(WebSecurityConfig.class);
    
    @Autowired
    private SecurityAuthenticationProvider securityAuthenticationProvider;
    
//  @Autowired
//  private AuthSuccessHandler authSuccessHandler;//登录成功跳转页面
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        LOGGER.debug("WebSecurityConfig.configure(HttpSecurity http)");
        http
            .exceptionHandling().accessDeniedPage("/error/403").and()
            .anonymous().and()
            .servletApi().and()
            .headers().cacheControl()
            .and().and()
            .authorizeRequests().antMatchers("/favicon.ico","/static/plugins/**","/static/css/**",
                        "/static/fonts/**","/static/login/**","/login").permitAll()
            
//          .antMatchers(HttpMethod.POST, "/login").permitAll() // 所有 /login 的POST请求 都放行
            
                .anyRequest().authenticated() //所有其他请求需要进行身份验证
            .and()
                .formLogin() // 基于 Form
                .loginPage("/login").permitAll()// 表单登录验证
                .and().logout().permitAll()
                
            .and()
                // 由于使用的是JWT,我们这里不需要csrf
                .csrf().disable().sessionManagement()
                // 基于token,所以不需要session
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);    
            // 禁用缓存
            http.headers().cacheControl();
            
            http
                // 添加一个过滤器 所有访问 /login 的请求交给 JWTLoginFilter 来处理 这个类处理所有的JWT相关内容
                .addFilterBefore(new JWTLoginFilter("/login", authenticationManager()),UsernamePasswordAuthenticationFilter.class)
                // 添加一个过滤器验证其他请求的Token是否合法
                .addFilterBefore(new JWTAuthenticationFilter(),UsernamePasswordAuthenticationFilter.class);
    }
    
     // 使用自定义身份验证组件
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        LOGGER.debug("使用自定义身份验证组件WebSecurityConfig.configure(AuthenticationManagerBuilder auth)");
        auth.authenticationProvider(securityAuthenticationProvider);
    }

}
package cn.etstone.evm.configuration.security;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import cn.etstone.evm.navigation.mapper.NavigationMapper;
import cn.etstone.evm.system.entity.NavigationDTO;
import cn.etstone.evm.system.entity.RoleNavigationDTO;
import cn.etstone.evm.system.entity.UserRoleNavigationInfo;
import cn.etstone.evm.system.mapper.UserRoleMapper;

@Service
public class SecurityAuthenticationProvider implements AuthenticationProvider { //自定义UserDetailsService 接口
    
    private static final Logger LOGGER = LoggerFactory.getLogger(SecurityAuthenticationProvider.class);

    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private NavigationMapper navigationMapper;
    
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        if(authentication == null || StringUtils.isBlank(authentication.getName()) || StringUtils.isBlank((String)authentication.getCredentials())){
            return null;
        }
        
        LOGGER.debug("authentication:{}",authentication);
        
        String username = authentication.getName();
        LOGGER.debug("authentication.getName();:{}",authentication.getName());
        String password = (String) authentication.getCredentials();
        LOGGER.debug("password:{}",password);
        
        UserRoleNavigationInfo userRoleInfo = userRoleMapper.findLoginName(username);
        LOGGER.debug("userRoleInfo:{}",userRoleInfo);
        
        List<NavigationDTO> findAllNavigationDTO = navigationMapper.findAllNavigationDTO();
        LOGGER.debug("findAllNavigationDTO:{}",findAllNavigationDTO);
        
        if(userRoleInfo == null){
            LOGGER.debug("账户不存在userRoleInfo:{} ",userRoleInfo);
            throw new UsernameNotFoundException("账户不存在");
        }
        
        if(!userRoleInfo.getUserPassword().equals(password)){
            LOGGER.debug("密码错误userRoleInfo:{} ",userRoleInfo);
            throw new UsernameNotFoundException("密码错误");
        }
        
        if(userRoleInfo.getUserState().equalsIgnoreCase("DISABLE")){
            LOGGER.debug("用户没启用userRoleInfo:{} ",userRoleInfo);
            throw new UsernameNotFoundException("用户没启用");
        }
        
        List<RoleNavigationDTO> roleNavigationDTOs = userRoleInfo.getRoleNavigationDTOs();
        if(roleNavigationDTOs == null || roleNavigationDTOs.isEmpty()){
            LOGGER.debug("用户没权限userRoleInfo:{} ",userRoleInfo);
            throw new UsernameNotFoundException("用户没权限");
        }
        
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        for (RoleNavigationDTO roleNavigationDTO : roleNavigationDTOs) {
            List<NavigationDTO> navigationDTOs = roleNavigationDTO.getNavigationDTOs();
            if(navigationDTOs == null || navigationDTOs.isEmpty()){
                LOGGER.debug("用户绑定访问权限为空userRoleInfo:{} ",userRoleInfo);
                throw new UsernameNotFoundException("用户绑定访问权限为空");
            }
            for (NavigationDTO navigationDTO : navigationDTOs) {
                if(navigationDTO.getNaviPId() == 0){
                    String roleName = "ROLE_" + navigationDTO.getNaviName();
                    authorities.add(new SimpleGrantedAuthority(roleName));
                }else{
                    for (NavigationDTO navigation : findAllNavigationDTO) {
                        if(navigationDTO.getNaviPId() == navigation.getNaviId()){
                            String roleName = "ROLE_" + navigation.getNaviName() + "." + navigationDTO.getNaviName();
                            authorities.add(new SimpleGrantedAuthority(roleName));
                        }
                    } 
                }
            }
            
        }
        
//      System.err.println(authorities);
        LOGGER.debug("登录成功");
        return new UsernamePasswordAuthenticationToken(userRoleInfo.getLoginName(),userRoleInfo.getUserPassword(), authorities);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
    
    
}
package cn.etstone.evm.configuration.jwt;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import cn.etstone.evm.configuration.EVMApplicationContext;
/**
 * 最先进入验证
 * @author feng
 *
 */
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {

    private static final Logger LOGGER = LoggerFactory.getLogger(JWTLoginFilter.class);
    
    public JWTLoginFilter(String url, AuthenticationManager authManager) {
        super(new AntPathRequestMatcher(url));
        LOGGER.debug("JWTLoginFilter.JWTLoginFilter(String url, AuthenticationManager authManager) ");
        setAuthenticationManager(authManager);
    }

    // 登录时需要验证时候调用
    @Override
    public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)
            throws AuthenticationException, IOException, ServletException {
        LOGGER.debug("登录时需要验证时候调用JWTLoginFilter.attemptAuthentication(HttpServletRequest req, HttpServletResponse res)");
        String loginName = req.getParameter("username");
        String password = req.getParameter("password");
        LOGGER.debug("username:{};password:{}",loginName,password);
        if(StringUtils.isBlank(loginName) || StringUtils.isBlank(password)){
            LOGGER.warn("登录时需要验证时候调用:{}未获取到登录名或密码",loginName,password);
            String json = JSONResult.fillResultString(401, "没有登录名或密码", JSONObject.NULL);
            res.setCharacterEncoding("UTF-8");
            res.setContentType("application/json;charset=UTF-8");
            res.setStatus(HttpServletResponse.SC_OK);
            res.getOutputStream()
                    .write(json.getBytes("UTF-8"));
            return null;
        }
//      // 返回一个验证令牌
        return getAuthenticationManager()
                .authenticate(new UsernamePasswordAuthenticationToken(loginName, password));
    }

    // 登录验证成功后调用
    @Override
    protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain,
            Authentication auth) throws IOException, ServletException {
        LOGGER.debug("登录验证成功后调用JWTLoginFilter.successfulAuthentication:{},生成token");
        TokenAuthenticationService tokenAuthenticationService = EVMApplicationContext.getApplicationContext().getBean(TokenAuthenticationService.class);
        tokenAuthenticationService.createJWT(res, auth);
    }

    // 登录验证失败后调用,这里直接灌入500错误返回,由于同一JSON返回,HTTP就都返回200了
    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException failed) throws IOException, ServletException {
        LOGGER.debug("登录验证失败后调用JWTLoginFilter.unsuccessfulAuthentication");
        String json = JSONResult.fillResultString(401, failed.getLocalizedMessage(), JSONObject.NULL);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=UTF-8");
        response.setStatus(HttpServletResponse.SC_OK);
        response.getOutputStream()
                .write(json.getBytes("UTF-8"));
    }

}
package cn.etstone.evm.configuration.jwt;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;

import cn.etstone.evm.configuration.EVMApplicationContext;

/**
 * 登录之后验证
 * @author feng
 *
 */
public class JWTAuthenticationFilter extends GenericFilterBean {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(JWTAuthenticationFilter.class);
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws IOException, ServletException {
        LOGGER.debug("登录后验证令牌");
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse)response;
        System.err.println("Evm-Authorization");
        String header = req.getHeader("Evm-Authorization");
        LOGGER.debug("登录后验证令牌TOKEN:{}",header);
        if(StringUtils.isBlank(header)){
            LOGGER.debug("登录后验证令牌TOKEN有误:{}",header);
            String json = JSONResult.fillResultString(401, "令牌错误或失效", JSONObject.NULL);
            resp.setCharacterEncoding("UTF-8");
            resp.setContentType("application/json;charset=UTF-8");
            resp.setStatus(HttpServletResponse.SC_OK);
            resp.getOutputStream()
                    .write(json.getBytes("UTF-8"));
            resp.getOutputStream().flush();
            resp.getOutputStream().close();
            return;
        }
        
        TokenAuthenticationService tokenAuthenticationService = EVMApplicationContext.getApplicationContext().getBean(TokenAuthenticationService.class);
        Authentication authentication = tokenAuthenticationService.parseJWT(header);
        LOGGER.debug("登录后验证令牌TOKEN解析为:{}",authentication);
        if(authentication == null){
            LOGGER.warn("登录后验证令牌TOKEN错误或失效",authentication);
            String json = JSONResult.fillResultString(401, "令牌错误或失效", JSONObject.NULL);
            resp.setCharacterEncoding("UTF-8");
            resp.setContentType("application/json;charset=UTF-8");
            resp.setStatus(HttpServletResponse.SC_OK);
            resp.getOutputStream()
                    .write(json.getBytes("UTF-8"));
            resp.getOutputStream().flush();
            resp.getOutputStream().close();
            return;
        }
        
        
        SecurityContextHolder.getContext().setAuthentication(authentication);
        resp.addHeader("Evm-Authorization", header);
        LOGGER.debug("验证令牌TOKEN成功,验证令牌TOKEN重新返回客户端");
        filterChain.doFilter(request, response);
    }
}
package cn.etstone.evm.configuration.jwt;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.security.sasl.AuthenticationException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service;

import cn.etstone.evm.configuration.properties.TokenPropertie;
import cn.etstone.evm.navigation.mapper.NavigationMapper;
import cn.etstone.evm.system.entity.NavigationDTO;
import cn.etstone.evm.system.entity.RoleNavigationDTO;
import cn.etstone.evm.system.entity.UserRoleNavigationInfo;
import cn.etstone.evm.system.mapper.UserRoleMapper;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

/**
 * 添加构造jwt及解析jwt的帮助类JwtHelper.java
 * 
 * @author feng
 *
 */
@Service
public class TokenAuthenticationService {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(TokenAuthenticationService.class);

    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private NavigationMapper navigationMapper;
    @Autowired
    private TokenPropertie tokenPropertie;
    
    
    /**
     * 解析jwt 获取登录名
     * 
     * @param jsonWebToken
     * @return
     * @throws ServletException
     * @throws AuthenticationException
     */
    @Cacheable(value="system", keyGenerator="evmKeyGenerator")
    public  Authentication parseJWT(String jsonWebToken) {
        LOGGER.debug("解析jwt:{}",jsonWebToken);
        if (jsonWebToken == null || jsonWebToken.isEmpty()) {
            return null;
        }
        try {
            Claims claims = null;
            claims = Jwts.parser().setSigningKey(tokenPropertie.getSecret()) // 验签
                    .parseClaimsJws(jsonWebToken).getBody();
            if ("EVM".equals(claims.getIssuer())) {
                String loginName = claims.getAudience();
                LOGGER.debug("解析jwt成功获取登录名:{}",loginName);
                if(StringUtils.isBlank(loginName)){
                    LOGGER.debug("解析jwt未获取到登录名");
                    return null;
                }
                UserRoleNavigationInfo userRoleNavigationInfo = userRoleMapper.findLoginName(loginName);
                if(userRoleNavigationInfo == null){
                    LOGGER.debug("解析jwt未找到用户");
                    return null;
                }
                List<NavigationDTO> findAllNavigationDTO = navigationMapper.findAllNavigationDTO();//获取全部权限
                List<RoleNavigationDTO> roleNavigationDTOs = userRoleNavigationInfo.getRoleNavigationDTOs();
                if(roleNavigationDTOs == null || roleNavigationDTOs.isEmpty()){
                    LOGGER.debug("解析jwt未找到用户权限");
                    return null;
                }
                
                List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
                for (RoleNavigationDTO roleNavigationDTO : roleNavigationDTOs) {
                    List<NavigationDTO> navigationDTOs = roleNavigationDTO.getNavigationDTOs();
                    if(navigationDTOs == null || navigationDTOs.isEmpty()){
                        LOGGER.debug("解析jwt未找到用户权限");
                        return null;
                    }
                    for (NavigationDTO navigationDTO : navigationDTOs) {
                        if(navigationDTO.getNaviPId() == 0){
                            String roleName = "ROLE_" + navigationDTO.getNaviName();
                            authorities.add(new SimpleGrantedAuthority(roleName));
                        }else{
                            for (NavigationDTO navigation : findAllNavigationDTO) {
                                if(navigationDTO.getNaviPId() == navigation.getNaviId()){
                                    String roleName = "ROLE_" + navigation.getNaviName() + "." + navigationDTO.getNaviName();
                                    authorities.add(new SimpleGrantedAuthority(roleName));
                                }
                            } 
                        }
                    }
                    
                }
                LOGGER.debug("解析jwt令牌成功登录名:{},权限:{}",loginName,authorities);
                return loginName != null ? new UsernamePasswordAuthenticationToken(loginName, null, authorities) : null;
            } else {
                LOGGER.warn("解析jwt令牌错误失败");
                return null;
            }
        } catch (Exception e) {
            LOGGER.warn("解析jwt失败:{}");
            return null;
        }
    }

    /**
     * 生成jwt
     * 
     * @param authentication
     * @return
     */
    public void createJWT(HttpServletResponse response, Authentication authentication) {
        // 权限
        /*  Collection<? extends GrantedAuthority> authorities =
          authentication.getAuthorities(); List<String> roles = new
          ArrayList<String>(); 
          for (GrantedAuthority grantedAuthority : authorities)
          { roles.add(grantedAuthority.getAuthority()); }*/
          
        // 生成JWT
        LOGGER.debug("生成jwt authentication:{}",authentication);
        String jwt = Jwts.builder().setId(UUID.randomUUID().toString()) // ID
                .setIssuer(tokenPropertie.getIssuer()) // 发布者
                .setAudience(authentication.getName()) // 用户名
                // .claim("roles", roles) // 权限
                .setExpiration(new Date(tokenPropertie.getExpirationtime())) // 有效期设置
                .signWith(SignatureAlgorithm.HS256, tokenPropertie.getSecret()).compact(); // 签名设置
        LOGGER.debug("生成jwt jwt成功:{}",jwt);
        try {
            response.setContentType("application/json");
            response.setStatus(HttpServletResponse.SC_OK);
            response.getOutputStream().println(JSONResult.fillResultString(0, "", jwt));
            response.getOutputStream().flush();
            response.getOutputStream().close();
        } catch (IOException e) {
            e.printStackTrace();
        }

//      return jwt;
    }
}
package cn.etstone.evm.configuration.jwt;

import org.json.JSONObject;

public class JSONResult {
    public static String fillResultString(Integer status, String message, Object result){
        JSONObject jsonObject = new JSONObject(){{
            put("status", status);
            put("message", message);
            put("result", result);
        }};
        return jsonObject.toString();
    }
}
package cn.etstone.evm.configuration;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class EVMApplicationContext implements ApplicationContextAware {
    
    private static ApplicationContext applicationContext = null;

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        EVMApplicationContext.applicationContext = applicationContext;
    }

}
package cn.etstone.evm.interceptor;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Optional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;

import com.google.gson.Gson;

import cn.etstone.evm.common.BizException;
import cn.etstone.evm.configuration.jwt.JSONResult;
import cn.etstone.evm.status.entity.Status;
import cn.etstone.evm.status.enums.BizCode;

/**
 * 异常拦截<br/>
 * 拦截所有未处理的异常
 * @author cpc
 *
 */
@RestControllerAdvice
public class ExceptionInterceptor {

    private static final Logger LOG = LoggerFactory.getLogger(ExceptionInterceptor.class);
    private static final Gson GSON = new Gson();
    
    private static final BizCode DEFAULT_CODE = BizCode.SERVER_EXCEPTION;
    
    private static final String DEFAULT_ERROR_PAGE = "/500";

    @Autowired
    private MessageSource messageSource;
    
    /**
     * 异常处理器
     */
    @ExceptionHandler(value={Exception.class})
    public ModelAndView exceptionHandler(Exception exception, WebRequest request){
        LOG.error("捕获到未处理异常, 异常: {}, {}, {}", exception.getMessage(), request.getContextPath(), request.getDescription(true));
        if(LOG.isDebugEnabled()){
            exception.printStackTrace();
        }
        
        String messageCode = String.format("%s.%s", DEFAULT_CODE.getPrefix(), DEFAULT_CODE.getMessage());
        String message = this.messageSource.getMessage(messageCode, null, null, LocaleContextHolder.getLocale());
        ModelAndView errorView = new ModelAndView("redirect:" + DEFAULT_ERROR_PAGE);
        errorView.addObject("message", message);
        return errorView;
    }
    
    @ExceptionHandler(value={AccessDeniedException.class})
    public void accessDeniedExceptionHandler(Exception exception, WebRequest request, HttpServletResponse response) throws Exception, IOException{
        LOG.error("未授权...");
        LOG.error("捕获到未处理异常, 异常: {}", exception.getMessage());
        if(LOG.isDebugEnabled()){
//          exception.printStackTrace();
        }
        response.setContentType("application/json;charset=UTF-8");
        String json = JSONResult.fillResultString(302, "权限不够", JSONObject.NULL);
        response.getOutputStream()
        .write(json.getBytes("UTF-8"));
        response.flushBuffer();
    }
    
    
    /**
     * 自定义BizException异常处理器
     * @throws IOException 
     */
    @ExceptionHandler(value={BizException.class})
    public void bizExceptionHandler(Exception exception, HttpServletRequest request, HttpServletResponse response) throws IOException{
        if(LOG.isDebugEnabled()){
            exception.printStackTrace();
        }
        BizException bizException = (BizException)exception;
        int code = bizException.getCode();
        Optional<BizCode> bizCode = BizCode.of(code);
        String message = null;
        if(bizCode.isPresent()){
            String messageCode = String.format("%s.%s", bizCode.get().getPrefix(), bizCode.get().getMessage());
            message = this.messageSource.getMessage(messageCode, null, null, LocaleContextHolder.getLocale());
        }
        
        if(message == null){
            LOG.error("自定义BizException异常处理器: 未找到异常信息中的BizCode信息. 使用默认BizCode: {}", DEFAULT_CODE);
            String messageCode = String.format("%s.%s", DEFAULT_CODE.getPrefix(), DEFAULT_CODE.getMessage());
            message = this.messageSource.getMessage(messageCode, null, null, LocaleContextHolder.getLocale());
            if(message == null){
                LOG.error("自定义BizException异常处理器: 未找到默认BizCode信息. 默认BizCode: {}", DEFAULT_CODE);
                message = "";
            }
        }
        
        Status<Object> status = new Status<Object>(HttpStatus.OK, code, message, null);
        LOG.debug("自定义BizException异常处理器: {}", status);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(GSON.toJson(status));
        response.flushBuffer();
    }
}

相关文章

网友评论

      本文标题:spring boot security jwt

      本文链接:https://www.haomeiwen.com/subject/abkqhxtx.html