SpringSecuritySpringBoot方式笔记

SpringSecurity配置笔记–boot

一、什么是SpringSecurity

Spring Security 最早不叫 Spring Security ,叫 Acegi Security,叫 Acegi Security 并不是说它和 Spring 就没有关系了,它依然是为 Spring 框架提供安全支持的。事实上,Java 领域的框架,很少有框架能够脱离 Spring 框架独立存在。Acegi Security 基于 Spring,可以帮助我们为项目建立丰富的角色与权限管理,但是最广为人诟病的则是它臃肿繁琐的配置,这一问题最终也遗传给了 Spring Security。

当 Acegi Security 投入 Spring 怀抱之后,先把这个名字改了,这就是大家所见到的 Spring Security 了,然后配置也得到了极大的简化。

但是和 Shiro 相比,人们对 Spring Security 的评价依然中重量级、配置繁琐。

二、有什么功能

对于一个权限管理框架而言,无论是 Shiro 还是 Spring Security,最最核心的功能,无非就是两方面:
认证
授权
通俗点说,认证就是我们常说的登录,授权就是权限鉴别,看看请求是否具备相应的权限。

Spring Security 支持多种不同的认证方式,这些认证方式有的是 Spring Security 自己提供的认证功能,有的是第三方标准组织制订的,主要有如下一些:
一些比较常见的认证方式:
HTTP BASIC authentication headers:基于IETF RFC 标准。
HTTP Digest authentication headers:基于IETF RFC 标准。
HTTP X.509 client certificate exchange:基于IETF RFC 标准。
LDAP:跨平台身份验证。
Form-based authentication:基于表单的身份验证。
Run-as authentication:用户用户临时以某一个身份登录。
OpenID authentication:去中心化认证。

除了这些常见的认证方式之外,一些比较冷门的认证方式,Spring Security 也提供了支持。
Jasig Central Authentication Service:单点登录。
Automatic “remember-me” authentication:记住我登录(允许一些非敏感操作)。
Anonymous authentication:匿名登录。

三、SpringSecurity的使用

使用默认配置的Security
1、引入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
2、默认什么都不配置(在yml中配置用户名和密码)
spring:
  security:
    user:
      name: user
      password: 552310
3、登陆效果

在这里插入图片描述

使用自定义配置(不使用数据库)
1、引入依赖
2、创建配置类并进行配置
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/test/**").authenticated()
                .and()
                .formLogin()
                .loginProcessingUrl("/test/login")
                .successHandler(new AuthenticationSuccessHandler(){
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                        httpServletResponse.setContentType("application/json;charset=utf-8");
                        PrintWriter out = httpServletResponse.getWriter();
                        out.write("{\"status\":\"success\",\"message\":\"登录成功!\"}");
                        out.flush();
                        out.close();
                    }
                })
                .failureHandler(new AuthenticationFailureHandler(){
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
                        httpServletResponse.setContentType("application/json;charset=utf-8");
                        PrintWriter out = httpServletResponse.getWriter();
                        out.write("{\"status\":\"error\",\"message\":\"账号或密码错误!\"}");
                        out.flush();
                        out.close();
                    }
                })
                .and()
                .csrf().disable();;
    }
}
3、登陆效果

在这里插入图片描述

使用数据库进行用户登陆验证
1、引入依赖
2、创建配置类
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
	private UserService userService;

    @Bean
    public PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance();
	}

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/test/**").authenticated()
                .and()
                .formLogin()
                .loginProcessingUrl("/test/login")
                .successHandler(new AuthenticationSuccessHandler(){
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                        httpServletResponse.setContentType("application/json;charset=utf-8");
                        PrintWriter out = httpServletResponse.getWriter();
                        out.write("{\"status\":\"success\",\"message\":\"登录成功!\"}");
                        out.flush();
                        out.close();
                    }
                })
                .failureHandler(new AuthenticationFailureHandler(){
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
                        httpServletResponse.setContentType("application/json;charset=utf-8");
                        PrintWriter out = httpServletResponse.getWriter();
                        out.write("{\"status\":\"error\",\"message\":\"账号或密码错误!\"}");
                        out.flush();
                        out.close();
                    }
                })
                .and()
                .exceptionHandling()
                .authenticationEntryPoint((request, response, authException) -> {
                    response.setContentType("application/json;charset=utf-8");
                    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                    PrintWriter out = response.getWriter();
                    out.write("{\"status\":\"error\",\"message\":\"授权已过期,请重新登录。\"}");
                    out.flush();
                    out.close();
                })
                .accessDeniedHandler((request, response, authException) -> {
                    response.setContentType("application/json;charset=utf-8");
                    response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                    PrintWriter out = response.getWriter();
                    out.write("{\"status\":\"error\",\"message\":\"您没有权限进行此操作!\"}");
                    out.flush();
                    out.close();
                })
                .and()
                .logout()
                .logoutUrl("/test/logout")
                .logoutSuccessHandler((request, response, authentication) -> {
                    response.setContentType("application/json;charset=utf-8");
                    PrintWriter out = response.getWriter();
                    out.write("{\"status\":\"success\",\"message\":\"注销成功!\"}");
                    out.flush();
                    out.close();
                })
                .and()
                .userDetailsService(userService)
                .csrf().disable();
    }

}
3、创建UserDetailService实现类
//接口
public interface UserService extends UserDetailsService{
    User getUserById(String uid);
    List<User> getUsers();
}

//接口实现类
@Service
public class UserServiceImpl implements UserService {

    @Autowired
	private UserMapper userMapper;

    @Override
    public User loadUserByUsername(String s) throws UsernameNotFoundException {
        User inputUser = new User();
        inputUser.setUsername(s);
        User user = userMapper.selectOne(inputUser);
        if (user == null) {
            throw new UsernameNotFoundException("找不到用户名为: " + s + "的用户");
        }
        return user;
	}

    @Override
    public User getUserById(String uid) {
        return userMapper.selectByPrimaryKey(uid);
	}

    @Override
    public List<User> getUsers() {
        return userMapper.selectAll();
    }

}

//实体类需要实现接口
public class User  implements UserDetails
4、登陆效果

在这里插入图片描述

四、SpringSecurity配置详解

配置段落含义
http
.authorizeRequests()
.antMatchers("/test/**")
.authenticated()
authorizeRequests()方法返回一个配置类,
antMatchers()在这个配置类上设置路径,
authenticated()表示test路径下的所有资源都需要进行认证。
.and()
.formLogin()
.loginProcessingUrl("/api/login")
.successHandler(
(request, response, authentication) -> {
…逻辑
})
.failureHandler(
(request, response, exception) -> {
…逻辑
})
and()方法使得上面一部分配置完成之后,返回到HttpSecurity方便进行下一项配置。
formLogin()会获取配置登陆的配置类,
loginProcessingUrl()中配置的路径为登陆用户名和密码所提交的url,
successHandler()和failureHandler()分别对应登陆成功和登陆失败后需要进行的操作。
.and()
.exceptionHandling()
.authenticationEntryPoint(
(request, response, authException) -> {
…逻辑
}).accessDeniedHandler(
(request, response, authException) -> {
…逻辑
})
exceptionHandling()方法返回出现异常时的配置类,
authenticationEntryPoint()方法处理认证出现异常的情况,
accessDeniedHandler()方法处理权限异常。
.and()
.logout()
.logoutUrl("/test/logout")
.logoutSuccessHandler(
(request, response, authentication) -> {
…逻辑
})
logout()返回用户注销时的配置类,
logoutUrl()设置注销时访问的Url,
logoutSuccessHandler()处理注销成功之后的逻辑。
.and()
.userDetailsService(userService)
.csrf()
.disable();
userDetailService()方法设置从数据库读取用户信息的类。
此类需要实现UserDetailsService接口并重写loadUserByUsername方法。
csrf().disable()关闭跨站请求伪造保护。

五、SpringSecurity配置类相关

1、配置类需要继承适配器

在这里插入图片描述

2、配置的三个方法
方法作用
configure(AuthenticationManagerBuilder auth)通过重载配置user-detail服务
configure(WebSecurity web)通过重载配置Security的Filter链
configure(HttpSecurity http)通过重载配置如何保护请求
3、了解用户是谁

1、通过给方法注入Authentication对象 通过对象的getPrincipal()获取

@GetMapping("/showuser")
public User showuser(Authentication auth){
    System.out.println(auth.getPrincipal());
    return (User)auth.getPrincipal();
}

2、在Controller方法上添加注解@AuthenticationPrincipal User user即可自动注入用户相关信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值