SpringSecurity---八個小實驗帶你掌握最基本的使用

實驗用到的模板

https://download.csdn.net/download/m2606707610/12122449

已上傳,免費下載。

在上一篇博客中我已經在HelloWorld中導入了該模板,大家可以參考上篇博客,來進行這篇博客的學習。

https://blog.csdn.net/m2606707610/article/details/104099005

第三章 SpringSecurity-實驗

1.實驗一:授權首頁和靜態資源

 配置類(AppWebSecurityConfig extends WebSecurityConfigurerAdapter

     重寫configure(HttpSecurity http)方法

@Configuration

@EnableWebSecurity

public class AppWebSecurityConfig extends WebSecurityConfigurerAdapter

@Override

protected void configure(HttpSecurity http) throws Exception {

//super.configure(http); //取消默認配置 

http.authorizeRequests()

.antMatchers("/layui/**","/index.jsp").permitAll() //設置匹配的資源放行

.anyRequest().authenticated(); //剩餘任何資源必須認證

}

}

測試結果

  1. 靜態資源和index.jsp都可以訪問
  2. 不存在的資源或有權限但不存在的資源404

   3.無權限的資源,403訪問被拒絕

             

2.實驗二:默認及自定義登錄頁

  1. 開啓formLogin()功能 ,http.formLogin()
  2. 靜態資源和index.jsp都可以訪問
  3. 不存在的資源
    1. http://localhost/spring-security-helloworld/xxx 重定向到登錄頁
    2. http://localhost:8080/springSecurityTest/login

http://localhost/spring-security-helloworld/layui/xxx  有權限時,找不到資源會報404錯誤

  1. 總結:默認表單登錄頁面的規則

1)、自動生成一個登錄頁

2)、登錄請求被默認提交到  /login    POST下

3)、生成隱藏域,可以防重複提交和跨站請求僞造;

<input name="_csrf" type="hidden" value="755f0b3c-0965-430b-852e-dcf6c77e7edb" />

爲了測試方便,先禁用這個功能: http.csrf().disable();

4)、默認提交的字段名爲:name='password'  name='username'

  1. 指定登錄頁
    1. http.formLogin().loginPage("/index.jsp"); //去到指定的登錄頁
    2. 靜態資源和index.jsp都可以訪問
    3. 不存在的資源
      1. http://localhost/spring-security-helloworld/xxx 重定向到自定義登錄頁
      2. http://localhost/spring-security-helloworld/layui/xxx 404錯誤
http.formLogin()//開啓表單登錄功能
                .loginPage("/toLogin")//自定義默認登錄頁,這裏toLogin爲轉向自己的登錄頁
                .usernameParameter("loginacct")//這裏指定自定義登錄頁的賬號name
                .passwordParameter("userpswd")//這裏指定自定義登錄頁的密碼name
                .loginProcessingUrl("/doLogin")//這指定的是自定義登錄頁表單提交的action,不指定則默認爲/login
                .defaultSuccessUrl("/main");//登陸成功後去到哪個頁面

 

3.3 實驗三:自定義表單登錄邏輯分析

  1. 表單提交地址:${PATH }/index.jsp
  2. 表單提交請求方式:post
  3. 表單提交請求失敗,提取錯誤消息:${SPRING_SECURITY_LAST_EXCEPTION.message}
  4. 如何提交表單:
    1. 引入jquery: <script src="${PATH }/layui/jquery.min.js"></script>
    2. $("form").submit();
    3. 表單提交參數名稱: username  password
  5. 提交請求被拒絕

暫時禁用csrf:http.csrf().disable();

  1. 登錄邏輯分析

/**默認登錄頁面

   * /login GET - the login form

   * /login POST - process the credentials and if valid authenticate the user

   * /login?error GET - redirect here for failed authentication attempts

   * /login?logout GET - redirect here after successfully logging out

 

   * 定製登錄頁面:loginPage("/index.jsp"):規定登錄頁的地址在哪裏

   * /index.jsp GET - the login form

   * /index.jsp POST - process the credentials and if valid authenticate the user

   * /index.jsp?error  GET - redirect here for failed authentication attempts

   * /index.jsp?logout GET - redirect here after successfully logging out

* ${SPRING_SECURITY_LAST_EXCEPTION.message}可以取出錯誤消息

   */

  1. 測試結果

3.4實驗四:自定義認證用戶信息

  1. 自定義認證用戶信息
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("zhangsan").password("123456").roles("ADMIN")
.and()
.withUser("lisi").password("123123").authorities("USER","MANAGER");
}
  1. CSRF跨站請求僞造
  1. SpringSecurity添加了csrf功能【DefaultCsrfToken】,所有的表單提交爲了防止跨站請求僞造,我們需要加上_csrf項; 或者,暫時禁用http.csrf().disable();

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>

    1. ${_csrf}  ===>>>  org.springframework.security.web.csrf.DefaultCsrfToken@19116cfd
    2. <input type="hidden" name="_csrf" value="310988c2-3f9d-4651-9e19-6ef4b2c4aa3a"/>

 

  1. 如果不禁用csrf,默認是開啓的狀態;頁面不設置csrf表單域,那麼,提交登錄請求會報錯

  1. 令牌值變化:
    1. 如果登錄成功(用戶名,密碼正確),令牌會被刪除,
    2. 重新回到登錄頁後退網頁,令牌會重新生成;
    3. 如果登錄失敗(用戶名,密碼錯誤),令牌不變。
    4. 刷新登錄頁,令牌值也不變
  2. 作用:  
    1. 防止別的網站僞造數據,提交請求到我們的網站。

  1. 擴展-瞭解XSS
  • XSS攻擊全稱跨站腳本攻擊,是爲不和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,故將跨站腳本攻擊縮寫爲XSS,XSS是一種在web應用中的計算機安全漏洞,它允許惡意web用戶將代碼植入到提供給其它用戶使用的頁面中。 
  • CSRF(Cross-site request forgery)跨站請求僞造,也被稱爲“One Click Attack”或者Session Riding,通常縮寫爲CSRF或者XSRF,是一種對網站的惡意利用。儘管聽起來像跨站腳本(XSS),但它與XSS非常不同,XSS利用站點內的信任用戶,而CSRF則通過僞裝成受信任用戶的請求來利用受信任的網站。與XSS攻擊相比,CSRF攻擊往往不大流行(因此對其進行防範的資源也相當稀少)和難以防範,所以被認爲XSS更具危險性

 

3.5實驗五:用戶註銷完成

  1. 添加註銷功能(logout)http.logout()默認規則           
  1. /logout:退出系統
  2. 如果csrf開啓,必須post方式的/logout請求,表單中需要增加csrf token
  3. logoutUrl();退出系統需要發送的請求,默認爲/logout
  4. logoutSuccessUrl();退出系統成功以後要跳轉的頁面地址
  5. addLogoutHandler():自定義註銷處理器
  6. deleteCookies():指定需要刪除的cookie
  7. invalidateHttpSession():session失效(DEBUG)

 

3.6 實驗六:基於角色的訪問控制

  1. 設置資源可以訪問的角色

http.authorizeRequests().antMatchers("/layui/**","/index.jsp").permitAll() //允許所有人都訪問靜態資源,無論登錄(認證)與否

.antMatchers("/level1/**").hasRole("學徒")

.antMatchers("/level2/**").hasRole("大師")

.antMatchers("/level3/**").hasRole("宗師")

.anyRequest().authenticated(); //放置最後,以上沒有規定的都需要權限認證。

  1. 注意:
    1. .anyRequest().authenticated()錯誤的設置在前面,後面的設置就不起作用了。
    2. 設置所有,"/**"都可以訪問,其他再進行的設置就不會起作用了
    3. 設置匿名訪問/level3/**  可以不用登錄,匿名訪問:.anyRequest().anonymous();
  2. 擁有該角色的資源可以訪問,否則不可以訪問

auth.inMemoryAuthentication()

.withUser("zhangsan").password("123456").roles("ADMIN","學徒","宗師")

.and()

.withUser("自定義訪問拒絕處理頁面,lisi").password("111111").authorities("USER","MANGER");

3.7 實驗七:自定義訪問拒絕處理頁面

  1. 直接增加處理映射界面

http.exceptionHandling().accessDeniedPage("/unauth.html");

  1. 在控制器類中增加映射處理

@RequestMapping("/unauth.html")

public String unauth(){

return "unauth";

}

  1. 增加顯示頁面,將main.jsp複製,命名爲unauth.jsp,增加一句提示信息

<h1>你無權訪問該頁面...</h1>

  1. 測試顯示效果

  1. 自定義異常處理器

http.exceptionHandling().accessDeniedHandler(new AccessDeniedHandler() {

@Override

public void handle(HttpServletRequest request, HttpServletResponse response,

AccessDeniedException accessDeniedException) throws IOException, ServletException {

request.setAttribute("message", accessDeniedException.getMessage());

request.getRequestDispatcher("/WEB-INF/views/unauth.jsp").forward(request, response);

}

});

3.8 實驗八:記住我功能

3.8.1 記住我功能-免登錄原理

  1. http.rememberMe();
  2. 默認規則
    1. 頁面checkbox提交remember-me參數
    2. 默認記住2周登錄狀態:AbstractRememberMeServices

    1. 會在cookie中保存名爲:remember-me的cookie
  1. 記住了以前登錄的狀態,以後再訪問就不用登錄了
  1. 登錄後頁面,關閉瀏覽器,直接訪問:

http://localhost/spring-security-helloworld/main.html 可以成功訪問,不必登錄。

  1. 這種方式,token值是放置在內存中的,服務器端重啓tomcat,token會失效。需要將token記錄在數據庫持久化纔不會失效。

3.8.2 記住我-數據版

  1. 引入pom.xml 包

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-orm</artifactId>

<version>4.3.20.RELEASE</version>

</dependency>

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>druid</artifactId>

<version>1.1.12</version>

</dependency>

<!-- mysql驅動 -->

<dependency>

    <groupId>mysql</groupId>

    <artifactId>mysql-connector-java</artifactId>

    <version>5.1.47</version>

</dependency>

  1. 配置數據源

<!-- 配置數據源 -->

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">

<property name="username" value="root"></property>

<property name="password" value="root"></property>

<property name="url" value="jdbc:mysql://192.168.137.3:3306/security?useSSL=false"></property>

<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>

</bean> 

<!--  jdbcTemplate-->

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">

<property name="dataSource" ref="dataSource"></property>

</bean>

  1. 創建表

create table persistent_logins (username varchar(64) not null, series varchar(64) primary key,token varchar(64) not null, last_used timestamp not null)

  1. 設置記住我

@Autowired

DataSource dataSource;

 

@Override

protected void configure(HttpSecurity http) throws Exception {

//。。。

//記住我

JdbcTokenRepositoryImpl ptr = new JdbcTokenRepositoryImpl();

ptr.setDataSource(dataSource);

http.rememberMe().tokenRepository(ptr);

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章