Maven 依赖
org.springframework.boot spring-boot-starter-securityorg.springframework.boot spring-boot-starter-web
编写Spring Security 配置类
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("1234").roles("admin");
}
}
- .首先我们自定义 SecurityConfig 继承自 WebSecurityConfigurerAdapter,重写里边的 configure 方法。
然后我们提供了一个 PasswordEncoder 的实例,因为目前的案例还比较简单,因此我暂时先不给密码进行加密,所以返回 NoOpPasswordEncoder 的实例即可。
configure 方法中,我们通过 inMemoryAuthentication 来开启在内存中定义用户,withUser 中是用户名,password 中则是用户密码,roles 中是用户角色。
如果需要配置多个用户,用 and 相连。
然后接下来我们继续完善前面的 SecurityConfig 类,继续重写它的configure(HttpSecurity http)和configure(WebSecurity web)方法,如下:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()
.and().formLogin().loginPage("/login.html").loginProcessingUrl("/doLogin").defaultSuccessUrl("/index").failureForwardUrl("/login.html")
.permitAll()
.and().csrf().disable();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/js
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()
.and().formLogin().loginPage("/login.html").loginProcessingUrl("/doLogin")
//登录成功处理
.successHandler(((request, response, authentication) -> {
Object principal = authentication.getPrincipal();
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write(new ObjectMapper().writevalueAsString(principal));
writer.flush();
writer.close();
}))
//登录失败处理
.failureHandler((request, response, exception) -> {
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write(exception.getMessage());
writer.flush();
writer.close();
})
.permitAll()
.and().csrf().disable()
//登录异常处理
.exceptionHandling()
.authenticationEntryPoint((request, response, authException) -> {
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write("请先登录");
writer.flush();
writer.close();
})
//登出处理
.and().logout().logoutUrl("/logout").logoutSuccessHandler((request, response, authentication) -> {
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write("注销成功");
writer.flush();
writer.close();
});
}
数据源和角色授权
例如上面的方式添加的用户使用auth.inMemoryAuthentication().withUser("user").password("1234").roles("admin")的方式添加(再添加可以使用.and()..withUser("admin")..),由于 Spring Security 支持多种数据源,例如内存、数据库、LDAP 等,这些不同来源的数据被共同封装成了一个 UserDetailService 接口,任何实现了该接口的对象都可以作为认证数据源。
因此我们还可以通过重写 WebSecurityConfigurerAdapter 中的 userDetailsService 方法来提供一个 UserDetailService 实例进而配置多个用户:
@Override
protected UserDetailsService userDetailsService() {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("dxayga").password("admin").roles("admin").build());
manager.createUser(User.withUsername("user").password("1234").roles("user").build());
return manager;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService());
}
我们可以给他添加可以访问的资源路径
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin
@Bean
RoleHierarchy roleHierarchy(){
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
roleHierarchy.setHierarchy("ROLE_admin > ROLE_user");
return roleHierarchy;
}
此配置代表ROLE_admin可以访问ROLE_user的资源了。



