spring整合SpringSecurity
- 导入依赖
<!-- SpringSecurity 对 Web 应用进行权限管理 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.2.10.RELEASE</version>
</dependency>
<!-- SpringSecurity 配置 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.2.10.RELEASE</version>
</dependency>
<!-- SpringSecurity 标签库 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>4.2.10.RELEASE</version>
</dependency>
- web.xml中配置过滤器:
<!-- 注意:这里的name必须是springSecurityFilterChain -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- SpringSecurity配置类:
@Configuration
@EnableWebSecurity
// 启用全局[方法权限控制]功能,并设置prePostEnabled为true。保证@PreAuthority/@PostAuthority/@PreFilter/@PostFilter生效
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebAppSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
/**
* 密码加密使用
*
* @return
*/
@Bean
public BCryptPasswordEncoder getBCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity security) throws Exception {
security.authorizeRequests() // 对请求进行授权
.antMatchers("/admin/to/login/page.do") // 针对登录页面进行设置
.permitAll() // 无条件访问
.antMatchers("/static/**") // 针对静态资源进行设置,无条件访问
.permitAll()
.anyRequest() // 其他请求
.authenticated() // 认证后访问
.and()
.exceptionHandling() // 设置无权访问时异常处理
// .accessDeniedPage("错误页面地址") // 直接跳转到页面,如果需要做处理则使用下面这个
.accessDeniedHandler(new AccessDeniedHandler() {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException {
// 设置页面提示信息
request.setAttribute("errorMsg", "抱歉!您没有访问该资源的权限!");
// 请求转发
request.getRequestDispatcher("/WEB-INF/page/common/system-error.jsp").forward(request, response);
}
}) // 处理方法[这里是返回一个错误提示页面]
.and()
.csrf()
.disable() // 禁用csrf,不然每个请求都需要带_csrf参数
.formLogin() // 开启表单登录的功能
.loginPage("/admin/to/login/page.do") // 指定登录页面
.loginProcessingUrl("/security/admin/do/login.do") // 指定登录请求
.defaultSuccessUrl("/admin/to/main/page.do") // 指定登录成功后跳转地址
.usernameParameter("loginAcct") // 设置账号的请求参数名称
.passwordParameter("userPswd") // 设置密码的请求参数名称
.and()
.logout() // 开启退出登录功能
.logoutUrl("/security/admin/do/logout.do") // 设置退出登录地址
.logoutSuccessUrl("/admin/to/login/page.do") // 设置退出登录成功后跳转地址
;
}
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception {
// 给登录的用户授权【从数据库中获取数据】,并给密码加密
builder.userDetailsService(userDetailsService).passwordEncoder(getBCryptPasswordEncoder());
}
}
自定义类实现UserDetailsService,装配User对象:
@Component
public class CrowdUserDetailsService implements UserDetailsService {
@Autowired
private AdminService adminService;
@Autowired
private RoleService roleService;
@Autowired
private AuthService authService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 1. 根据账号查询admin对象
Admin admin = adminService.getAdminByLoginAcct(username);
if (admin == null) {
return null;
}
Integer adminId = admin.getId();
// 2. 根据admin的id查询角色信息
List<Role> assignRoles = roleService.getAssignRole(adminId);
// 3. 根据admin的id查询权限信息
List<String> auths = authService.getAuthsByAdminId(adminId);
// 4. 封装权限和角色信息为【GrantedAuthority】对象
List<GrantedAuthority> authorities = new ArrayList<>();
for (Role assignRole : assignRoles) {
// 注意:SpringSecurity的角色要求需要加上【ROLE_】的前缀,以区别权限和角色
String roleName = "ROLE_" + assignRole.getName();
SimpleGrantedAuthority authority = new SimpleGrantedAuthority(roleName);
authorities.add(authority);
}
for (String auth : auths) {
// 注意:权限不需要添加前缀
SimpleGrantedAuthority authority = new SimpleGrantedAuthority(auth);
authorities.add(authority);
}
// 5. 封装SecurityAdmin对象
SecurityAdmin securityAdmin = new SecurityAdmin(admin, authorities);
return securityAdmin;
}
}