security權限控制

前言

spring自帶角色權限控制框架web

用戶-角色spring

數據庫和dimain

  • 數據庫
-- 用戶表
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)
)
  • domain
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>

web.xml引入

  • 引入filter
<!--配置框架使用的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>

service校驗方法

  • 在service中繼承spring接口
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());

不一樣角色訪問控制權限

jsp頁面

<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>

後臺

  • springmcv.xml
<!--手打才能自動引入-->
<security:global-method-security secured-annotations="enabled"></security:global-method-security>
  • controller
@Secured("ROLE_ADMIN")
public class RoleController
相關文章
相關標籤/搜索