最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

【环球速看料】从数据库查询权限信息与自定义失败处理

来源:博客园

从数据库查询权限信息

代码实现

我们只需要根据用户id去查询到其所对应的权限信息即可。


【资料图】

​         所以我们可以先定义个mapper,其中提供一个方法可以根据userid查询权限信息。

package com.example.qinghuatokendemo.Mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;import com.example.qinghuatokendemo.Domain.Menu;import org.apache.ibatis.annotations.Mapper;import java.util.List;@Mapperpublic interface MenuMapper extends BaseMapper {    List selectPermsByUserId(Long userid);}

尤其是自定义方法,所以需要创建对应的mapper文件,定义对应的sql语句

    

在application.yml中配置mapperXML文件的位置

spring:  datasource:    url: jdbc:mysql://localhost:3306/springsecurity?characterEncoding=utf-8&serverTimezone=UTC    username: root    password: njzyb555    driver-class-name: com.mysql.cj.jdbc.Drivermybatis-plus:  mapper-locations: classpath*:/mapper/**/*.xml

测试类

package com.example.qinghuatokendemo;import com.example.qinghuatokendemo.Domain.User;import com.example.qinghuatokendemo.Mapper.MenuMapper;import com.example.qinghuatokendemo.Mapper.UserMapper;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.crypto.password.PasswordEncoder;import java.util.List;@SpringBootTestpublic class MapperTest {    @Autowired    private UserMapper userMapper;    @Autowired    private MenuMapper menuMapper;    @Autowired    private PasswordEncoder passwordEncoder;    @Test    public void TestBCryptPasswordEncoder(){        //$2a$10$9CmQULPcw8prFL.gnmM/zO1bDtPtVNb4mTxNs2wHsm7xonGMCvT2C        System.out.println(passwordEncoder.                matches("1234", "$2a$10$eAQvguaa3mHMt7cUrXeQnu3vIw74tbNtthm/t1gH6IMrRihv1OpRu"));        /*String encode = passwordEncoder.encode("1234");        System.out.println(encode);*/    }    @Test    public void testUser(){        List users = userMapper.selectList(null);        System.out.println(users);    }    @Test    public void testselectPermsByUserId(){        List list = menuMapper.selectPermsByUserId(1L);        System.out.println(list);    }}

自定义失败处理

​ 我们还希望在认证失败或者是授权失败的情况下也能和我们的接口一样返回相同结构的json,这样可以让前端能对响应进行统一的处理。要实现这个功能我们需要知道SpringSecurity的异常处理机制。

​ 在SpringSecurity中,如果我们在认证或者授权的过程中出现了异常会被ExceptionTranslationFilter捕获到。在ExceptionTranslationFilter中会去判断是认证失败还是授权失败出现的异常。

​ 如果是认证过程中出现的异常会被封装成AuthenticationException然后调用AuthenticationEntryPoint对象的方法去进行异常处理。

​ 如果是授权过程中出现的异常会被封装成AccessDeniedException然后调用AccessDeniedHandler对象的方法去进行异常处理。

​ 所以如果我们需要自定义异常处理,我们只需要自定义AuthenticationEntryPoint和AccessDeniedHandler然后配置给SpringSecurity即可。

自定义实现类

package com.example.qinghuatokendemo.Handler;import com.alibaba.fastjson.JSON;import com.example.qinghuatokendemo.Domain.ResponseResult;import com.example.qinghuatokendemo.Utils.WebUtils;import org.springframework.http.HttpStatus;import org.springframework.security.core.AuthenticationException;import org.springframework.security.web.AuthenticationEntryPoint;import org.springframework.stereotype.Component;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@Componentpublic class AccessDeniedHandlerImpl implements AuthenticationEntryPoint {    @Override    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {        ResponseResult result = new ResponseResult(HttpStatus.INTERNAL_SERVER_ERROR.value(),"用户认证失败请查询登录");        String json = JSON.toJSONString(request);        //处理异常        WebUtils.renderString(response,json);    }}
package com.example.qinghuatokendemo.Handler;import com.alibaba.fastjson.JSON;import com.example.qinghuatokendemo.Domain.ResponseResult;import com.example.qinghuatokendemo.Utils.WebUtils;import org.springframework.http.HttpStatus;import org.springframework.security.access.AccessDeniedException;import org.springframework.security.web.access.AccessDeniedHandler;import org.springframework.stereotype.Component;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@Componentpublic class AccessDeniedHandlerImpl implements AccessDeniedHandler {    @Override    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {        ResponseResult result = new ResponseResult(HttpStatus.FORBIDDEN.value(), "权限不足");        String json = JSON.toJSONString(result);        WebUtils.renderString(response,json);    }}
package com.example.qinghuatokendemo.Config;import com.example.qinghuatokendemo.Handler.AccessDeniedHandlerImpl;import com.example.qinghuatokendemo.filter.JwtAuthenticationTokenFilter;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.authentication.AuthenticationManager;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.WebSecurityConfigurerAdapter;import org.springframework.security.config.http.SessionCreationPolicy;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.crypto.password.PasswordEncoder;import org.springframework.security.web.AuthenticationEntryPoint;import org.springframework.security.web.access.AccessDeniedHandler;import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;@Configuration@EnableGlobalMethodSecurity(prePostEnabled = true)public class SecurityConfig extends WebSecurityConfigurerAdapter {    @Bean    public PasswordEncoder passwordEncoder(){        return new BCryptPasswordEncoder();    }    @Autowired    JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;    @Autowired    private AuthenticationEntryPoint authenticationEntryPoint;    @Autowired    private AccessDeniedHandler accessDeniedHandler;    @Override    protected void configure(HttpSecurity http) throws Exception {       /* http                //关闭csrf                .csrf().disable()                //不通过Session获取SecurityContext                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)                .and()                .authorizeRequests()                // 对于登录接口 允许匿名访问                .antMatchers("/user/login").anonymous()                // 除上面外的所有请求全部需要鉴权认证                .anyRequest().authenticated();*/        http                .csrf().disable()                .sessionManagement()                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)                .and()                .authorizeRequests()                .antMatchers("/hello").permitAll()                .antMatchers("/user/login").anonymous()                .anyRequest().authenticated();        //把token校验过滤器添加到过滤器链中        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);        //配置异常处理器        http.exceptionHandling()                //认证失败处理器                .authenticationEntryPoint(authenticationEntryPoint).accessDeniedHandler(accessDeniedHandler);    }    @Bean    @Override    public AuthenticationManager authenticationManagerBean() throws Exception {        return super.authenticationManagerBean();    }}

关键词: