spring自帶角色權限控制框架web
用戶-角色spring
-- 用戶表 CREATE TABLE sys_user( id int auto_increment PRIMARY KEY , username VARCHAR(50), email VARCHAR(50) , PASSWORD VARCHAR(80), phoneNum VARCHAR(20), STATUS int(1) ); -- 角色表 CREATE TABLE sys_role( id int auto_increment PRIMARY KEY, roleName VARCHAR(50) , roleDesc VARCHAR(50) ) -- 用戶和角色中間表 CREATE TABLE sys_user_role( userId int, roleId int, PRIMARY KEY(userId,roleId), FOREIGN KEY (userId) REFERENCES sys_USER(id), FOREIGN KEY (roleId) REFERENCES sys_role(id) )
public class SysUser { private Long id; private String username; private String email; private String password; private String phoneNum; private int status; private List<Role> roles; } public class Role { private Long id; private String roleName; private String roleDesc; }
403.jsp
login.jsp
error.jspsql
springSecurity.xml數據庫
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:security="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <!--放行未登陸訪問的頁面--> <security:http pattern="/login.jsp" security="none"></security:http> <security:http pattern="/error.jsp" security="none"></security:http> <security:http pattern="/css/**" security="none"></security:http> <security:http pattern="/img/**" security="none"></security:http> <security:http pattern="/pages/**" security="none"></security:http> <security:http pattern="/plugins/**" security="none"></security:http> <!--配置攔截器的路徑規則 auto-config="true" 表示使用權限框架默認的配置 use-expressions="false" 關閉權限框架的表達式 spel intercept-url 攔截請求資源的路徑 access="ROLE_USER" 容許訪問的條件 當前用戶必須擁有ROLE_USER的角色才能夠訪問 --> <security:http auto-config="true" use-expressions="true"> <!--權限框架支持多種角色的登陸 角色之間的關係爲or 或者的關係--> <security:intercept-url pattern="/**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"></security:intercept-url> <!--自定義頁面的配置節點--> <security:form-login login-page="/login.jsp" login-processing-url="/login" default-target-url="/index.jsp" authentication-failure-url="/error.jsp"></security:form-login> <!--登陸成功權限不足的處理--> <security:access-denied-handler error-page="/403.jsp"></security:access-denied-handler> <!--csrf關閉跨域請求的攻擊--> <security:csrf disabled="true"></security:csrf> <!-- logout 退出請求的url路徑 實際是頁面點擊按鈕請求的地址 logout-success-url 成功註銷後 跳轉的頁面 invalidate-session 設置session失效 --> <security:logout logout-url="/logOut" logout-success-url="/login.jsp" invalidate-session="true"></security:logout> </security:http> <!--配置攔截後驗證的節點--> <security:authentication-manager> <security:authentication-provider user-service-ref="userService"> <!--自定義的加密工具類--> <security:password-encoder ref="pwdEncoder"></security:password-encoder> </security:authentication-provider> </security:authentication-manager> <!--配置自定義的加密工具類,這裏使用自帶的--> <bean id="pwdEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean> <!--開啓註解支持--> <security:global-method-security secured-annotations="enabled"/> </beans>
<!--配置框架使用的filter過濾器--> <filter> <!--過濾器執行鏈名臣固定springSecurityFilterChain--> <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>
<!--spring的listener--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml,classpath:springSecurity.xml</param-value> </context-param>
public interface SysUserService extends UserDetailsService { @Override UserDetails loadUserByUsername(String username) throws UsernameNotFoundException; }
@Service("userService") public class SysUserServiceImpl implements SysUserService { @Autowired private SysUserDao userDao; @Autowired BCryptPasswordEncoder pwdEncoder; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { //獲得數據庫的用戶 SysUser sysUser = userDao.findUserByName(username); //框架的User對象用於驗證返回 用戶名 密碼 用戶的權限集合 //查詢獲得用戶真正的角色集合返回 List<Role> roles =sysUser.getRoles(); List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); ///若是當前用戶確實擁有角色 循環添加到集合中 if(roles!=null&&roles.size()>0){ for (Role role : roles) { authorities.add(new SimpleGrantedAuthority(role.getRoleName())); } } User user = new User(sysUser.getUsername(),sysUser.getPassword(),authorities); return user; } }
# 方式一 ${ sessionScope.SPRING_SECURITY_CONTEXT.authentication.principal.username } # 方式二 <security:authentication property="principal.username"/>
// 先獲取到SecurityContext對象 SecurityContext context = SecurityContextHolder.getContext(); // 獲取到認證的對象 Authentication authentication = context.getAuthentication(); // 獲取到登陸的用戶信息 User user = (User) authentication.getPrincipal(); System.out.println(user.getUsername());
<security:authorize access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"> <li id="system-setting"> <a href="${pageContext.request.contextPath}/product/findByPageHelper"> <i class="fa fa-circle-o"></i> 產品管理 </a> </li> </security:authorize>
<!--手打才能自動引入--> <security:global-method-security secured-annotations="enabled"></security:global-method-security>
@Secured("ROLE_ADMIN") public class RoleController