123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- package com.gihon.configSecurity.config;
- import com.gihon.configSecurity.encoder.MyPasswordEncoder;
- import com.gihon.configSecurity.handler.MyAccessDeniedHandler;
- import com.gihon.configSecurity.handler.MyFailureHandler;
- import com.gihon.configSecurity.handler.MySuccessHandler;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.security.config.annotation.web.builders.HttpSecurity;
- import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.crypto.password.PasswordEncoder;
- import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
- import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
- import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
- import javax.sql.DataSource;
- /**
- * SpringSecurity的配置类型
- * 继承父类型WebSecurityConfigurerAdapter
- * WebSecurityConfigurerAdapter是一个Security提供的配置模板,可以快速实现
- * Security配置,简化自定义配置的复杂度。
- *
- * SpringSecurity提供的默认环境,如:登录页面、登录处理请求(/login)、拦截处理(未登录访问其他地址自动跳转到登录页面)
- * 只有在不提供自定义Security配置的时候,才有效。
- *
- * Security要求自定义的UserDetailsService配置配套提供一个PasswordEncoder类型的对象,
- * 对象中提供密码的加密和匹配逻辑,为认证提供加密处理。
- * 如果spring环境中没有PasswordEncoder类型的对象,UserDetailsService类型的对象无效。
- */
- @Configuration
- public class MySecurityConfiguration extends WebSecurityConfigurerAdapter {
- /**
- * 在Security中,处理认证逻辑的具体代码,不需要提供控制器逻辑。
- * 因为Security根据配置formLogin().loginProcessingUrl()自动做控制跳转。
- * 跳转逻辑是:
- * 找UserDetailsService接口的实现类型对象,调用启动的方法loadUserByUsername,实现登录认证。
- * @param http
- * @throws Exception
- */
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- // 设置登录页面路径地址是 '/'
- // http.formLogin() // 获取Security中专门用来配置登录相关逻辑的配置类型
- // .usernameParameter("name") // 设置请求参数中,用户名的参数名称
- // .passwordParameter("pswd") // 设置请求参数中,密码的参数名称
- // .loginPage("/") // 配置登录页面请求地址是什么。
- //.loginProcessingUrl("/login") // 使用POST访问,访问什么地址的时候,实现认证逻辑。登录地址。
- // 认证成功或失败,Security会转发请求,到指定的地址。转发的请求是POST方式的。需要定义控制器处理。
- // .successForwardUrl("/success") // 登录成功后,跳转地址。 请求转发, 重复登录。
- // .defaultSuccessUrl("/success") // 登录成功后,重定向到指定位置
- // .successHandler(new MySuccessHandler("/security/success")) // 登录成功后,自定义处理逻辑。
- // .failureForwardUrl("/fail"); // 登录失败后,跳转地址
- // .failureUrl("/fail"); // 登录失败后,响应重定向
- // .failureHandler(new MyFailureHandler("/security/fail")); // 登录失败后,自定义处理逻辑
- /**
- * 设置权限相关
- * 可以通过对ExpressionUrlAuthorizationConfigurer配置,实现对URL地址的权限管理。
- * 可以定义针对固定地址、表达式地址的权限控制。
- * 常用权限控制方法:
- * 1、 permitAll() - 全权限访问,任意客户端都可访问。
- * 2、 authenticated() - 必须认证后才能访问。登录后才能访问。
- * 3、 denyAll() - 无访问权限。 没有登录的时候,要求登录;登录后,显示403无访问权限错误。
- * 4、 anonymous() - 匿名访问。可以不登录就访问的资源。和permitAll类似。
- * 5、 rememberMe() - 记住我。当认证的时候,开启了rememberMe功能,可以使用记住我访问。
- * 6、 fullyAuthenticated() - 完整认证才可访问。 rememberMe不能访问。
- *
- * 联合使用:
- * 如: antMatchers("/", "/index").permitAll(); 请求 "/" 或 "/index" 的时候,授予所有权限。
- * 基于角色和权限的访问控制:
- * 必须建立在已认证的基础上,才会执行对应的访问控制。
- * 1、 基于角色的访问控制:
- * URL匹配().hasRole | hasAnyRole
- * hasRole(String role) - 判断已登录的用户权限集合中,是否包含参数角色
- * 底层是调用的access("hasRole('ROLE_"+role+"')")
- * hasAnyRole(String... roles) - 判断已登录的用户权限集合中,是否包括参数中的任意角色。
- * 底层是调用的access("hasAnyRole('ROLE_角色1','ROLE_角色2'....)")
- * 2、 基于权限的访问控制:
- * hasAuthority(String authority) - 判断已登录的用户权限集合中,是否包含权限
- * 底层: access("hasAuthority('权限')")
- * hasAnyAuthority(String... authorities) - 判断已登录的用户权限集合中,是否包含参数中任意权限
- * 底层: access("hasAnyAuthority('权限1','权限2'....)")
- * 3、 基于IP的访问控制:
- * hasIpAddress(String ipAddress) 检查客户端IP是否是参数指定的IP
- * 客户端IP是: HttpServletRequest.getRemoteAddr()方法的返回值。
- * 底层: access("hasIpAddress('IP地址')")
- */
- http.authorizeRequests() // 获取Security中专门配置权限管理的配置类型
- .antMatchers("/login").permitAll()
- .antMatchers("/doc.html","/webjars/**","/img.icons/**","/swagger-resources/**","/v2/api-docs").permitAll()
- // .antMatchers("/", "/fail").permitAll() // 访问 '/' 地址的时候,不需要登录。
- // .antMatchers("/**/*.js").permitAll() // 只处理js文件
- // .regexMatchers(".+[.]css").permitAll() // 只处理css
- // .antMatchers("/anonymous").anonymous() // 匿名访问
- // .antMatchers("/denyAll").denyAll() // 不能访问
- // .antMatchers("/hasAdminRole").hasRole("管理员") // 判断有没有"管理员"角色
- // .antMatchers("/hasUserRole").hasRole("普通用户") // 判断有没有"普通用户"角色
- // .antMatchers("/hasAnyRole").hasAnyRole("管理员", "普通用户") // 判断是否包含管理员或普通用户角色。
- // .antMatchers("/hasAuthority").hasAuthority("userManagement")
- // .antMatchers("/hasAnyAuthority").hasAnyAuthority("userManagement","selfManagement")
- // .antMatchers("/accessRole").access("hasRole('ROLE_管理员')")// 使用access,角色控制
- // .antMatchers("/accessAuthority").access("hasAuthority('selfManagement')")// 使用access,权限控制
- // WebSecurityExpressionRoot
- //.antMatchers("/*").access("@myPermissionsMatcherImpl.hasPermission(request,authentication)")
- .anyRequest().authenticated(); // 所有的请求地址,都必须登录才能访问。
- // 异常处理配置
- http.exceptionHandling().accessDeniedHandler(new MyAccessDeniedHandler());
- // 配置rememberMe, 使用rememberMe功能的时候,认证成功结果跳转,一定要使用重定向。
- http.rememberMe()
- .rememberMeParameter("rememberMe") // 设置请求参数名,默认为remember-me
- .rememberMeCookieName("rememberMe") // 设置记住我的cookie名称。默认为remember-me
- .tokenValiditySeconds(300) // 设置rememberMe有效时长。默认14天。
- .userDetailsService(userLoginServiceImpl) // 设置用户认证逻辑对象
- .tokenRepository(tokenRepository); // 设置rememberMe数据持久化对象。持久化用户认证成功后的主体。
- // 退出配置, 注销配置
- http.logout()
- .invalidateHttpSession(true) // 退出的时候,销毁HttpSession对象。默认true
- .clearAuthentication(true) // 退出的时候,清空已认证用户主体对象。默认true
- .logoutUrl("/security/logout") // 退出登录的请求地址。默认是 /logout
- .logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET"))
- .logoutSuccessUrl("/security/"); // 退出后的跳转地址,重定向。 默认是 loginPage?logout
- // csrf安全处理, 关闭csrf。 防止恶意攻击的技术。 security4+ 默认开启的。
- http.csrf().disable();
- }
- // @Autowired
- // private DataSource dataSource;
- // rememberMe数据保存对象,相当于是DAO
- @Bean
- public PersistentTokenRepository persistentTokenRepository(DataSource dataSource){
- // 使用Spring-JDBC技术,实现rememberMe数据的存储。保存到数据库。
- // 在JdbcTokenRepositoryImpl类型的对象中,必须提供一个DataSource对象。
- JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
- jdbcTokenRepository.setDataSource(dataSource);
- // rememberMe表格的创建, 只能在系统第一次启动的时候创建。 默认是false,不会启动创建表格。
- // jdbcTokenRepository.setCreateTableOnStartup(true);
- return jdbcTokenRepository;
- }
- @Autowired
- private UserDetailsService userLoginServiceImpl;
- @Autowired
- private PersistentTokenRepository tokenRepository;
- // 传递的构造参数BCryptPasswordEncoder(int strength), 建议为8的整数倍。
- @Bean
- public PasswordEncoder passwordEncoder(){
- return new MyPasswordEncoder();
- }
- }
|