开发过程中遇到了权限控制的问题,学习完Security,代码抽取如下:
<filter>
<!--
DelegatingFilterProxy用于整合第三方框架(代理过滤器,非真正的过滤器,真正的过滤器需要在spring的配置文件)
整合Spring Security时过滤器的名称必须为springSecurityFilterChain,
否则会抛出NoSuchBeanDefinitionException异常
-->
<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>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<!--定义哪些资源可以放行,匿名用户可以访问-->
<security:http security="none" pattern="/js/**" />
<security:http security="none" pattern="/css/**" />
<security:http security="none" pattern="/img/**" />
<security:http security="none" pattern="/plugins/**" />
<security:http security="none" pattern="/login.html"></security:http>
<!--开启注解方式权限控制-->
<security:global-method-security pre-post-annotations="enabled" />
<security:http auto-config="true" use-expressions="true">
<!--定义哪些资源需要获得权限才能放行,只要认证通过就可以访问,非匿名用户-->
<security:intercept-url pattern="/pages/**" access="isAuthenticated()" />
<!--定义表单登录信息-->
<security:form-login login-page="/login.html"
username-parameter="username"
password-parameter="password"
login-processing-url="/login.do"
default-target-url="/pages/main.html"
authentication-failure-url="/login.html"
always-use-default-target="true"
/>
<!--关闭csrf-->
<security:csrf disabled="true"/>
<!--设置页面保护策略-->
<security:headers>
<!--设置在页面可以通过iframe访问受保护的页面,默认为不允许访问-->
<security:frame-options policy="SAMEORIGIN"></security:frame-options>
</security:headers>
<!--退出登录-->
<!-- <security:logout logout-url="/logout.do"
logout-success-url="/login.html" invalidate-session="true"/>-->
</security:http>
<!--配置密码加密对象-->
<bean id="bCryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<!--认证管理-->
<security:authentication-manager>
<security:authentication-provider user-service-ref="springSecurityUserService">
<!--指定密码加密策略-->
<security:password-encoder ref="bCryptPasswordEncoder"/>
</security:authentication-provider>
</security:authentication-manager>
</beans>
两个地方需要修改:
<!--批量扫描-->
<dubbo:annotation package="com.xxx" />
<import resource="classpath:spring-security.xml"/>
在该web工程中新建一个xxx.xxx.security.SpringSecurityUserService类
import com.alibaba.dubbo.config.annotation.Reference;
import com.xxx.pojo.Permission;
import com.xxx.pojo.Role;
import com.xxx.service.UserService;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@Component
public class SpringSecurityUserService implements UserDetailsService {
@Reference
private UserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 根据用户名查询数据库中是否存在该用户
com.xxx.pojo.User userDB = userService.findUserByUsername(username);
if (userDB == null) {
// 数据库无该用户
return null;
}
// 获取密码
String password = userDB.getPassword();
// 获取该用户的权限
List<GrantedAuthority> list = new ArrayList<>();
Set<Role> roles = userDB.getRoles();
for (Role role : roles) {
Set<Permission> permissions = role.getPermissions();
for (Permission permission : permissions) {
list.add(new SimpleGrantedAuthority(permission.getKeyword()));
}
}
UserDetails userDetails = new User(username, password, list);
return userDetails;
}
}
<!--
① 配置哪些链接可以放行(没有认证通过也可以访问的资源)
security="none":没有权限
pattern="/login.html":没有任何权限,可以访问login.html
-->
<security:http security="none" pattern="/login.html"></security:http>
<security:global-method-security pre-post-annotations="enabled" />
<!--
② 定义哪些链接不可以放行(必须通过认证才能访问的资源),及需要有角色,有权限才可以放行访问资源
<security:http auto-config="true" use-expressions="true">
auto-config="true":开启自动配置 由springsecurity提供登录页面,提供登录的url地址,退出的url地址
use-expressions="true":使用表达式的方式控制权限
security:intercept-url:定义哪些链接不可以放行,需要当前角色和权限才能放行
pattern="/**":要求系统中的所有资源,都必须通过角色和权限才能访问
access:指定角色和权限
如果使用表达式use-expressions="true"
access="hasRole(‘ROLE_ADMIN‘):表示具有ROLE_ADMIN的角色才能访问系统的资源
如果不使用表达式use-expressions="false"
access="ROLE_ADMIN:表示具有ROLE_ADMIN的角色才能访问系统的资源
-->
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/**" access="hasRole(‘ROLE_ADMIN‘)"></security:intercept-url>
</security:http>
<!--
form-login:定义表单登录信息
login-page="/login.html":表示指定登录页面
username-parameter="username":使用登录名的名称,默认值是username
password-parameter="password":使用登录名的密码,默认值是password
login-processing-url="/login.do":表示登录的url地址
default-target-url="/index.html":登录成功后的url地址
authentication-failure-url="/login.html":认证失败后跳转的url地址,失败后指定/login.html
always-use-default-target="true":登录成功后,始终跳转到default-target-url指定的地址,即登录成功的默认地址
-->
<security:form-login login-page="/login.html"
username-parameter="username"
password-parameter="password"
login-processing-url="/login.do"
default-target-url="/index.html"
authentication-failure-url="/login.html"
always-use-default-target="true"
/>
<!--
csrf:对应CsrfFilter过滤器
disabled:是否启用CsrfFilter过滤器,如果使用自定义登录页面需要关闭此项,否则登录操作会被禁用(403)
-->
<security:csrf disabled="true"></security:csrf>
<security:headers>
<!--设置在页面可以通过iframe访问受保护的页面,默认为不允许访问-->
<security:frame-options policy="SAMEORIGIN"></security:frame-options>
</security:headers>
<!--配置密码加密对象-->
<bean id="bCryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<!--认证管理
user-service-ref:对应一个javaBean
-->
<security:authentication-manager>
<security:authentication-provider user-service-ref="springSecurityUserService">
<!--指定密码加密策略-->
<security:password-encoder ref="bCryptPasswordEncoder"/>
</security:authentication-provider>
</security:authentication-manager>
原文:https://www.cnblogs.com/tianwenxin/p/14983307.html