SpringBoot中对SpringSecurity的基本使用

参考文献:

Spring Security Architecture

基本使用:

添加依赖:

<!-- 安全框架 Spring Security -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

自定义的User对象:


/**
 * 自定义的 User 对象
 * 此 User 类不是我们的数据库里的用户类,是用来安全服务的
 */
public class AnyUser extends User {
    //import org.springframework.security.core.userdetails.User;
 
    private Long id;
 
    private String nickname;
 
    AnyUser(
            String username,
            String password,
            Collection<? extends GrantedAuthority> authorities
    ) {
        super(username, password, authorities);
    }
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public String getNickname() {
        return nickname;
    }
 
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
}

继承UserDetailsService:
首先这里我们需要重写UserDetailsService接口,然后实现该接口中的loadUserByUsername方法,通过该方法查询到对应的用户,这里之所以要实现UserDetailsService接口,是因为在Spring Security中我们配置相关参数需要UserDetailsService类型的数据。

Spring Security 支持把权限划分层次,高层次包含低层次的权限,比如`ROLE_AMDIN,ROLE_USER`两个权限,若用户拥有了ROLE_AMDIN权限,那么相当于有了ROLE_USER权限。用户被授权了ADMIN,那么就相当于有其他所有的权限。

/**
 * 自定义 UserDetailsService
 */
@Service
class AnyUserDetailsService implements UserDetailsService {
 
    private final UserService userService;
 
    public AnyUserDetailsService(UserService userService){
        this.userService = userService;
    }
 
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        com.zhou.model.User user = userService.getByEmail(s);
        if (user == null){
            throw new UsernameNotFoundException("用户不存在");
        }
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        //对应的权限添加
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        AnyUser anyUser = new AnyUser(s, user.getPassword(), authorities);
        anyUser.setId(user.getId());
        anyUser.setNickname(user.getNickname());
        return anyUser;
    }
 
}

安全控制中心:

/**
 * 安全控制中心
 */
@EnableWebSecurity//@EnableWebMvcSecurity 注解开启Spring Security的功能
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
    private final UserDetailsService userDetailsService;
 
    public WebSecurityConfig(AnyUserDetailsService userDetailsService){
        this.userDetailsService = userDetailsService;
    }
 
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(this.userDetailsService);
    }
 
    /**
     * http.authorizeRequests()
     .anyRequest().authenticated()
     .and().formLogin().loginPage("/login")
     //设置默认登录成功跳转页面
     .defaultSuccessUrl("/index").failureUrl("/login?error").permitAll()
     .and()
     //开启cookie保存用户数据
     .rememberMe()
     //设置cookie有效期
     .tokenValiditySeconds(60 * 60 * 24 * 7)
     //设置cookie的私钥
     .key("")
     .and()
     .logout()
     //默认注销行为为logout,可以通过下面的方式来修改
     .logoutUrl("/custom-logout")
     //设置注销成功后跳转页面,默认是跳转到登录页面
     .logoutSuccessUrl("")
     .permitAll();
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()//authorizeRequests() 定义哪些URL需要被保护、哪些不需要被保护
                .antMatchers("/user/**","/news/**").authenticated()
                .anyRequest().permitAll()
                .and()
                .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/user", true)
                .permitAll()
                .and()
                .logout()
                .permitAll()
                .and().csrf().disable();
    }
 
}

Spring Security提供了一个过滤器来拦截请求并验证用户身份。如果用户身份认证失败,页面就重定向到/login?error,并且页面中会展现相应的错误信息。若用户想要注销登录,可以通过访问@{/logout}请求,在完成注销之后,页面展现相应的成功消息。

自定义登录成功处理逻辑:

使登陆成功后跳到登录前页面:


//处理登录成功的。
@Component("myAuthenticationSuccessHandler")
public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
 
    @Autowired
    private ObjectMapper objectMapper;
 
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException {
        //什么都不做的话,那就直接调用父类的方法
        super.onAuthenticationSuccess(request, response, authentication);
 
        String url=request.getRequestURI();
 
        //如果是要跳转到某个页面的
        new DefaultRedirectStrategy().sendRedirect(request, response, url);
 
    }
}

重新配置安全中心(代码完成之后,修改配置config类代码。添加2个注解,自动注入):


@Autowired
private AuthenticationSuccessHandler myAuthenticationSuccessHandler;

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()//authorizeRequests() 定义哪些URL需要被保护、哪些不需要被保护
                .antMatchers("/user/**","/news/**","/blog/manage/**","/blog/create/**").authenticated()
                .anyRequest().permitAll()
                .and()
                .formLogin()
                .loginPage("/login")
                .successHandler(myAuthenticationSuccessHandler)//登陆成功处理
                .permitAll()
                .and()
                .logout()
                .permitAll()
                .and().csrf().disable();
    }
扫描二维码关注公众号,回复: 2340210 查看本文章

猜你喜欢

转载自blog.csdn.net/codertnt/article/details/81134540
今日推荐