SpringSecurity之二:web自定义用户登录

官方文档:Hello Spring Security :: Spring Security

目录

一、认证流程

二、自定义认证实现

2.1实现UserDetailsService接口

2.2 配置自定义登录页面

一、认证流程

先了解下SpringSecurity认证的流程,如下图(图片来自官网):

SpringSecurity之二:web自定义用户登录_第1张图片step1:用户提交请求,AbstractAuthenticationProcessingFilter会从请求信息中生成Authentication对象,Authentication对象根据 AbstractAuthenticationProcessingFilter子类决定;

step2:通过AuthenticationManager对Authentication进行认证;

step3:登录成功执行4,登录失败执行3;

二、自定义认证实现

web服务,用户登录基本都是通过form表单提交,所以重点看form认证的实现。

认证流程和上图一样,过滤器是UsernamePasswordAuthenticationFilter,继承AbstractAuthenticationProcessingFilter

2.1实现UserDetailsService接口

通过扩展UserDetailsService#loadUserByUsername接口来获取数据库中保存的用户信息,security将接口返回的正确用户信息与用户提交的信息进行认证,来实现登录校验。

@Service
public class MyUserDetailService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // todo 根据用户名进行数据库查询,如果查不到对应账号,则抛出UsernameNotFoundException
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String password = encoder.encode("1234");
        List authorities = AuthorityUtils.createAuthorityList("admin");
        return User.withUsername("janice").password(password).authorities(authorities).build();
    }

}
说明:即使接口没有设置访问的角色和资源权限,authorities也必须要设置,否则登录会报错,如图:

SpringSecurity之二:web自定义用户登录_第2张图片

 启动服务验证,登录成功

SpringSecurity之二:web自定义用户登录_第3张图片

2.2 配置自定义登录页面

项目中往往都是需要有自己的登录页面,这时就需要进行一些配置来实现。

先在static下加一个简单的页面,用于测试:

SpringSecurity之二:web自定义用户登录_第4张图片

 注意(可查看源码UsernamePasswordAuthenticationFilter#attemptAuthentication):

1、input中的name,必须和源码中的用户名和密码命名一下,否则会取不到提交的数据;

2、请求必须是POST请求,否则不会进行处理;

SpringSecurity之二:web自定义用户登录_第5张图片

重写protected void configure(HttpSecurity http),配置自定义登录页面

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyUserDetailService myUserDetailService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailService).passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .loginPage("/login.html")  // 登录页面
                .loginProcessingUrl("/user/login")  // 登录接口,与form表单提交链接对应
                .defaultSuccessUrl("/index.html").permitAll() // 登录成功后跳转链接
                .and().authorizeRequests()
                .antMatchers("/user/login").permitAll()  // 设置免登录链接
                .anyRequest().authenticated()
                .and().csrf().disable();  // 关闭csrf防护
    }

}

注意:csrf需先关闭,否则会对POST、PUT、DELETE请求进行csrf验证,登录请求不会通过。

启动服务进行测试

跳转到了自定页的登录页面

SpringSecurity之二:web自定义用户登录_第6张图片

2.3 接口授权

2.3.1 配置中增加接口所需的权限

方法有:hasAuthority、hasAnyAuthority、hasRole、hasAnyRole

SpringSecurity之二:web自定义用户登录_第7张图片

用户信息中加上数据库中查到的用户拥有的角色和资源权限

SpringSecurity之二:web自定义用户登录_第8张图片 注意(具体原因见源码截图):

1、User对象中有设置资源和角色两种接口,但不能同时使用.authorities(authorities).roles(""),因为roles接口也是用authorities实现,最后的配置会覆盖前面的配置,导致用户权限缺失;

2、authorities中设置角色权限,需要加上前缀:ROLE_;

SpringSecurity之二:web自定义用户登录_第9张图片

2.3.2 使用注解

@Secured({"ROLE_tester"})
@PreAuthorize("hasAnyAuthority('admin')")

开启注解:@EnableGlobalMethodSecurity(prePostEnabled = true)

启动服务,测试

SpringSecurity之二:web自定义用户登录_第10张图片 SpringSecurity之二:web自定义用户登录_第11张图片SpringSecurity之二:web自定义用户登录_第12张图片

2.4 自定义403页面

对于无访问权限的接口,需要配置跳转自定义无权限访问页面,只需要加上

http.exceptionHandling().accessDeniedPage("/unauth.html");

加一个简单的html页面,启动服务测试:

SpringSecurity之二:web自定义用户登录_第13张图片

 2.5 自定义退出

你可能感兴趣的:(SpringSecurity,SpringBoot,SpringSecurity,spring,boot)