spring-security 起步

pom.xml

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.1.2.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-web</artifactId>
      <version>5.1.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-config</artifactId>
      <version>5.1.2.RELEASE</version>
    </dependency>

加入過濾器

  1. 選擇一:web.xml
  <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>
  1. 選擇二:AbstractSecurityWebApplicationInitializer
package cn.johnyu;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer {

}

配置安全策略

  1. 使用配置文件,加入security的名稱空間(暫時不可用)
<?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 auto-config="true">
    <security:intercept-url pattern="/**" access="ROLE_SPITTER"></security:intercept-url>
</security:http>
</beans>
  1. 使用配置類(繼承WebSecurityConfigurerAdapter
package cn.johnyu.security;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     *用來修改過濾器鏈
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/css/**");
        web.ignoring().antMatchers("/images/**");
        web.ignoring().antMatchers("/js/**");
    }

    /**
     *配置UserDetailService,完成"鑒權"
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication().dataSource(dataSource)
                .passwordEncoder(new StandardPasswordEncoder("53cr3t"));
    }
    /**
     * 修改攔截器,保護請求
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
                http.authorizeRequests()
                .antMatchers("/work")
                .hasAuthority("ROLE_READER")
                .antMatchers("/other")
                .hasAnyRole("GUEST","READER")
                .anyRequest().permitAll()
                .and()
                .formLogin()

                .and()
                .exceptionHandling()
                .accessDeniedPage("/forbidden")
                .and()
                .logout()
                .logoutUrl("/logout");
    }
}

關于登錄頁

  1. 如果沒有Override configure(HttpSecurity),則會提供一個默認的登錄頁(否則沒有)
  2. 如果加入.formLogin(),則會找回該登錄頁
  3. 該頁核心內(nèi)容如下:
<form method="post" action="/WebApp_war_exploded/login">
    <input type="text"  name="username" >
    <input type="password"  name="password">
    <input name="_csrf" type="hidden" value="0386c20f-b2fe-426a-9e0f-d58c0fe254d1"/>
    <button  type="submit">Sign in</button>
</form>
  1. 你可以加入自定義的登錄頁,方法如下:
.formLogin()
                .loginPage("/login")
                .failureUrl("/login?error=true");

此時,如果有以下控制器

    @RequestMapping("/login")
    public String login(){
        return "login";
    }

則會將頁面轉(zhuǎn)向到自定義的頁面上。

關于退出

.and()
                .logout()
                .logoutUrl("/logout");

這將指定“/logout”為退出鏈接,退出后將回到“/login?logout”

關于role不符合

  1. 默認將返回403碼
  2. 指定403頁面的方法
.and()
                .exceptionHandling()
                .accessDeniedPage("/forbidden")

關于鑒權

  1. 可以使用void configure(AuthenticationManagerBuilder)進行
  2. 可以使用三種方法進行:
@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication();
        auth.inMemoryAuthentication();
        auth.ldapAuthentication();
    }
  1. 無論哪種方式,都將采用hash方式處理密碼

使用JDBC進行鑒權

  1. 直接使用(無定制方式)
private DataSource dataSource;
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication().dataSource(dataSource)
        .passwordEncoder(new StandardPasswordEncoder("53cr3t"));//這個是必選項
    }
  1. Security默認使用以下表的結構:schema.sql
-- ----------------------------
-- 用戶表: username做為唯一字段
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
                         `id` int(8) NOT NULL AUTO_INCREMENT,
                         `username` varchar(20) DEFAULT NULL,
                         `password` varchar(100) DEFAULT NULL,
                         `enabled` tinyint(4) DEFAULT NULL,
                         PRIMARY KEY (`id`)
);

-- ----------------------------
-- 角色表:username外鍵關聯(lián)users
-- 注意:它與用戶表,存在著間接的 Many To Many 的關系,用戶的角色可以來自:直接角色和所屬組的角色
-- ----------------------------
DROP TABLE IF EXISTS `authorities`;
CREATE TABLE `authorities` (
                               `id` int(11) NOT NULL AUTO_INCREMENT,
                               `username` varchar(20) DEFAULT NULL,
                               `authority` varchar(50) DEFAULT NULL,
                               PRIMARY KEY (`id`)
);

-- ----------------------------
-- 用戶組:
-- 注意:它與users存在 Many to Many的關系,但與authorities,是Many To One 的關系
-- ----------------------------
DROP TABLE IF EXISTS `groups`;
CREATE TABLE `groups` (
                          `id` int(11) NOT NULL AUTO_INCREMENT,
                          `groupname` varchar(50) DEFAULT NULL,
                          PRIMARY KEY (`id`)
);

-- ----------------------------
-- users 與 authorites 的一對一的關聯(lián)表,group_Id外鍵關聯(lián)groups表
-- ----------------------------
DROP TABLE IF EXISTS `group_authorities`;
CREATE TABLE `group_authorities` (
                                     `group_Id` int(11) NOT NULL AUTO_INCREMENT,
                                     `authority` varchar(50) DEFAULT NULL,
                                     PRIMARY KEY (`group_Id`)
);

-- ----------------------------
-- 用戶 與 用戶組 之間的多到多關聯(lián)關系(username外鍵關聯(lián)users表,group_Id外鍵關聯(lián)groups表)
-- ----------------------------
DROP TABLE IF EXISTS `group_members`;
CREATE TABLE `group_members` (
                                 `id` int(11) NOT NULL AUTO_INCREMENT,
                                 `username` varchar(20) DEFAULT NULL,
                                 `group_Id` int(11) DEFAULT NULL,
                                 PRIMARY KEY (`id`)
);

初如化的數(shù)據(jù):data.sql

-- 密碼為123(salt=53cr3t new StandardPasswordEncoder("53cr3t").encode("123"))
insert  into users (username,password,enabled) values('john','97c1e5a28f4d983316d375550e1e28ee50b6d27b5c5a71d6daa4c694227a8d8d94e8e6917ca4ad13',1);
insert  into users (username,password,enabled) values('tom','123',0);
insert  into users (username,password,enabled) values('alice','221a34d7021d75c196b80cbeb0ce53818871ab2a27be7113afc1ee1d08ab157c19cdef4490a06080',1);
-- 必須確保User具有Role
insert into authorities (username,authority) values('john','ROLE_READER');
insert into authorities (username,authority) values('tom','ROLE_READER');
insert into authorities (username,authority) values('alice','ROLE_GUEST');

附:三條核心查詢語句:

public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService, MessageSourceAware {
//用于用戶身份認證
    public static final String DEF_USERS_BY_USERNAME_QUERY = "select username,password,enabled from users where username = ?";
//查詢用戶的角色
    public static final String DEF_AUTHORITIES_BY_USERNAME_QUERY = "select username,authority from authorities where username = ?";
//查詢用戶所屬的組的角色
    public static final String DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY = "select g.id, g.group_name, ga.authority from groups g, group_members gm, group_authorities ga where gm.username = ? and g.id = ga.group_id and g.id = gm.group_id";
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容

  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,941評論 6 342
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,869評論 18 139
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong閱讀 22,522評論 1 92
  • Spring Security 學習 Spring Security是一種基于Spring AOP和Servlet...
    ChaLLengerZeng閱讀 1,113評論 0 0
  • 10.3 中秋還沒到, 興沖沖的跑過來找你,emm…團圓( ^ω^) 第一次坐臥鋪車的心情……(≧?≦)/ 來到你...
    leaves_C閱讀 385評論 0 0