一.入门(Spring Security在不进行任何配置下默认给出的用户user
密码随项目启动生成随机字符串)
1.添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
2.访问index首页的时候,系统会默认跳转到login页面进行登录认证
3.用户名默认是user,密码在项目启动时会自动生成
4.输入用户和密码即可正常访问
二.Spring Security用户密码配置其他方式
1.springboot配置文件中配置
spring:
security:
user:
name: admin # 用户名
password: 123456 # 密码
2.java代码在内存中配置
新建Security 核心配置类WebSecurityConfig继承WebSecurityConfigurerAdapter
@Configuration @EnableWebSecurity // 启用Spring Security的Web安全支持 public class WebSecurityConfig extends WebSecurityConfigurerAdapter { /** * 用户配置在内存中 * @param auth * @throws Exception */ @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 在内存中配置用户,配置多个用户调用`and()`方法 auth.inMemoryAuthentication().passwordEncoder(passwordEncoder())// 指定加密方式 .withUser("admin").password(passwordEncoder().encode("123")).roles("ADMIN") .and() .withUser("test").password(passwordEncoder().encode("456")).roles("TEST"); } /** * 配置加密方式 * @return */ @Bean public PasswordEncoder passwordEncoder() { //BCryptPasswordEncoder:Spring Security 提供的加密工具,可快速实现加密加盐 /*return new BCryptPasswordEncoder();*/ return new PasswordEncoder() { @Override public boolean matches(CharSequence rawPassword, String encodedPassword) { return encodedPassword.equals(encode(rawPassword)); } @Override public String encode(CharSequence rawPassword) { return Sha1.degest(rawPassword.toString()); } }; }
3.从数据库中获取用户账号、密码信息(实际中最常用方式)
自定义CustomUserDetailsService /** * 用户配置在数据库中_动态认证 * @param auth * @throws Exception */ @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder()); }
三. Spring Security 配置 登录处理 与 忽略拦截
/** * 登录处理 * @param http * @throws Exception */ @Override protected void configure(HttpSecurity http) throws Exception { //开启登录配置 http.authorizeRequests() // 标识访问 `/index` 这个接口,需要具备`ADMIN`角色 .antMatchers("/index").hasRole("ADMIN") // 允许匿名的url - 可理解为放行接口 - 多个接口使用,分割 .antMatchers( servicePrefix+"/", servicePrefix+"/csrf", servicePrefix + "/actuator/health/**", servicePrefix + "/auth/login", servicePrefix + "/public/**").permitAll() // 其余所有请求都需要认证 .anyRequest().authenticated() .and() // 设置登录认证页面 .formLogin().loginPage(servicePrefix + "/auth/login") // 登录成功后的处理器 .successHandler(authenticationSuccessHandler) // 登录失败的处理器 .failureHandler(authenticationFailHandler) .and() // 配置注销成功的处理 .logout().logoutUrl(servicePrefix + "/auth/logout").deleteCookies("SESSIONID", "JSESSIONID", "TGC") .logoutSuccessHandler(myLogoutSuccessHandler) .and() // 配置 Http Basic 验证 .httpBasic() .and() //关闭CSRF跨域 .csrf().disable(); // 配置跨域资源共享 http.cors(); // 是否允许配置请求缓存 http.requestCache().disable(); } /** * 忽略拦截 * @param web * @throws Exception */ @Override public void configure(WebSecurity web) throws Exception { // 设置拦截忽略url或者js/css等静态资源,将不会经过Spring Security过滤器链 web.ignoring().antMatchers(servicePrefix + "/swagger-ui.html", servicePrefix + "/swagger-resources/**", servicePrefix + "/v2/**", servicePrefix + "/webjars/springfox-swagger-ui/**", "/**/*.html", "/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg", "/**/*.ico","/**/*.svg", "/**/*.ttf","/**/*.woff", "/**/*.woff2"); }
最后,附上完整的security配置代码
1.WebSecurityConfig配置
@Configuration @EnableWebSecurity // 启用Spring Security的Web安全支持 public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Value("${spring.mvc.servlet.path}") private String servicePrefix; @Resource private AuthenticationSuccessHandler authenticationSuccessHandler; @Resource private AuthenticationFailHandler authenticationFailHandler; @Resource private MyLogoutSuccessHandler myLogoutSuccessHandler; @Resource private CustomUserDetailsService customUserDetailsService;/** * 用户配置在内存中_静态认证 * @param auth * @throws Exception */ /*@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 在内存中配置用户,配置多个用户调用`and()`方法 auth.inMemoryAuthentication().passwordEncoder(passwordEncoder())// 指定加密方式 .withUser("admin").password(passwordEncoder().encode("123")).roles("ADMIN") .and() .withUser("test").password(passwordEncoder().encode("456")).roles("TEST"); }*/ /** * 用户配置在数据库中_动态认证 * @param auth * @throws Exception */ @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder()); } /** * 配置加密方式 * @return */ @Bean public PasswordEncoder passwordEncoder() { //BCryptPasswordEncoder:Spring Security 提供的加密工具,可快速实现加密加盐 /*return new BCryptPasswordEncoder();*/ return new PasswordEncoder() { @Override public boolean matches(CharSequence rawPassword, String encodedPassword) { return encodedPassword.equals(encode(rawPassword)); } @Override public String encode(CharSequence rawPassword) { return Sha1.degest(rawPassword.toString()); } }; } /** * 登录处理 * @param http * @throws Exception */ @Override protected void configure(HttpSecurity http) throws Exception { //开启登录配置 http.authorizeRequests() // 标识访问 `/index` 这个接口,需要具备`ADMIN`角色 .antMatchers("/index").hasRole("ADMIN") // 允许匿名的url - 可理解为放行接口 - 多个接口使用,分割 .antMatchers( servicePrefix+"/", servicePrefix+"/csrf", servicePrefix + "/actuator/health/**", servicePrefix + "/auth/login", servicePrefix + "/public/**").permitAll() // 其余所有请求都需要认证 .anyRequest().authenticated() .and() // 设置登录认证页面 .formLogin().loginPage(servicePrefix + "/auth/login") // 登录成功后的处理器 .successHandler(authenticationSuccessHandler) // 登录失败的处理器 .failureHandler(authenticationFailHandler) .and() // 配置注销成功的处理 .logout().logoutUrl(servicePrefix + "/auth/logout").deleteCookies("SESSIONID", "JSESSIONID", "TGC") .logoutSuccessHandler(myLogoutSuccessHandler) .and() // 配置 Http Basic 验证 .httpBasic() .and() //关闭CSRF跨域 .csrf().disable(); // 配置跨域资源共享 http.cors(); // 是否允许配置请求缓存 http.requestCache().disable(); } /** * 忽略拦截 * @param web * @throws Exception */ @Override public void configure(WebSecurity web) throws Exception { // 设置拦截忽略url或者js/css等静态资源,将不会经过Spring Security过滤器链 web.ignoring().antMatchers(servicePrefix + "/swagger-ui.html", servicePrefix + "/swagger-resources/**", servicePrefix + "/v2/**", servicePrefix + "/webjars/springfox-swagger-ui/**", "/**/*.html", "/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg", "/**/*.ico","/**/*.svg", "/**/*.ttf","/**/*.woff", "/**/*.woff2"); } }
2.自定义 CustomUserDetailsService
@Component public class CustomUserDetailsService implements UserDetailsService { @Resource private UserMapper userMapper; @Override public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException { UserInfo loginUser = userMapper.selectOneByUserLoginId(userName); if (loginUser == null) { throw new UsernameNotFoundException("用户名为" + userName + "的用户不存在"); } List<Role> roles = loginUser.getRoles(); List<SimpleGrantedAuthority> authoritys = this.getAuthority(roles); /* 这里构建一个Security自带的User对象返回,其构造方法: username: 用户登录名 password: 用户登录密码 enabled: 用户是启用还是禁用 true-启用 false-禁用 accountNonExpired: 用户的帐户是否已过期 true-有效 false-过期 accountNonLocked: 用户是锁定还是解锁 true-未锁定 false-锁定 credentialsNonExpired: 用户的凭据(密码)是否已过期 true-凭据有效 false-凭据无效 authorities :用户权限(角色)集合 */ User userDetails = new User(loginUser.getUserLoginId(),loginUser.getPassword(), loginUser.getStatus() != 0,true,true,true,authoritys); return userDetails; } private List<SimpleGrantedAuthority> getAuthority(List<Role> roles) { List<SimpleGrantedAuthority> authoritys = new ArrayList<>(); for (Role role : roles) { authoritys.add(new SimpleGrantedAuthority("ROLE_"+role.getRoleName())); } return authoritys; } }
3.登陆成功处理器
@Component public class AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { @Resource private ObjectMapper objectMapper; @Resource private UserMapper userMapper; @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { UserDetails userDetails = (UserDetails) authentication.getPrincipal(); String username = userDetails.getUsername(); UserInfo userInfo = userMapper.selectOneByUserLoginId(username); response.setContentType("application/json;charset=UTF-8"); response.getWriter().write(objectMapper.writeValueAsString(RestResponse.success(userInfo))); } }
4.登陆失败处理器
@Component public class AuthenticationFailHandler extends SimpleUrlAuthenticationFailureHandler { @Resource private ObjectMapper objectMapper; @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { response.setContentType("application/json;charset=UTF-8"); response.getWriter().write(objectMapper.writeValueAsString(RestResponse.AUTHC_ERROR)); } }
5.注销成功处理器
@Component public class MyLogoutSuccessHandler implements LogoutSuccessHandler { @Resource private ObjectMapper objectMapper; @Override public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { request.getSession().invalidate(); response.setContentType("application/json;charset=UTF-8"); response.getWriter().write(objectMapper.writeValueAsString(RestResponse.notify("注销成功"))); } }
......
springsecurity方法级权限注解详见链接: https://www.cnblogs.com/Baker-Street/p/12893414.html