互聯網項目中,安全與權限控制是不可迴避的問題,爲了解決這一些列問題,許多安全框架應運而生了。這些框架旨在幫咱們解決公用的安全問題,讓咱們的程序更加健壯,從而讓程序員全身心投入到業務開發當中。那麼SpringSecurity出自於大名鼎鼎的Spring家族,同時能與SpringBoot,SpringCloud無縫集成,它也是業界流行的安全框架之一。css
注意:本示例是基於註解的springmvc構建,SpringBoot的版本對應的是2.0.3.REALEASE。Spring版本5.0.7REALEASE,SpringSecurity的版本是5.0.5html
首先添加SpringSecurity的依賴:java
compile('org.springframework.boot:spring-boot-starter-security')
緊接着按照以下目錄規範建立jquery
app包下主要爲Root WebApplicationContext提供配置,而web包下主要是爲servlet WebApplicationContext提供相關配置,這種方式更符合WebApplicationContext的層次化規範,同時也方便管理配置程序員
package com.bdqn.lyrk.security.study.app.config; import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; /** * 這個類能夠在添加springSecurity核心過濾器以前或以後作一些咱們須要的操做 * * @author chen.nie * @date 2018/6/8 **/ public class WebSecurityInitializer extends AbstractSecurityWebApplicationInitializer { }
package com.bdqn.lyrk.security.study.app.config; 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.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.User; /** * spring-security的相關配置 * * @author chen.nie * @date 2018/6/7 **/ @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { /* 1.配置靜態資源不進行受權驗證 2.登陸地址及跳轉事後的成功頁不須要驗證 3.其他均進行受權驗證 */ http. authorizeRequests().antMatchers("/static/**").permitAll(). and().authorizeRequests().anyRequest().authenticated(). and().formLogin().loginPage("/login").successForwardUrl("/toIndex").permitAll(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { /* 在內存中建立用戶 */ User.UserBuilder users = User.withDefaultPasswordEncoder(); auth.inMemoryAuthentication().withUser(users.username("admin").password("123").roles("ADMIN")); } }
該類主要是設置安全配置注意使用@EnableWebSecruity註解,咱們能夠在這裏設置Http的安全配置和最基本的認證配置等,其中在該代碼裏設置靜態資源 登陸頁 和登陸成功須要跳轉的頁面不用認證,另外基於內存設置了用戶adminweb
另外:loginPage()裏的值即爲跳轉頁面的路徑又爲處理登陸驗證的路徑。當get請求時爲前者而post請求時爲後者spring
package com.bdqn.lyrk.security.study.app; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; /** * 主配置類 * * @author chen.nie * @date 2018/6/8 **/ @Configuration @ComponentScan @PropertySource("classpath:application.properties") public class WebAppConfig { @Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } }
WebStartupInitializer:安全
package com.bdqn.lyrk.security.study.web; import com.bdqn.lyrk.security.study.app.WebAppConfig; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class WebStartupInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[]{WebAppConfig.class}; } @Override protected Class<?>[] getServletConfigClasses() { return new Class[]{WebMvcConfig.class}; } @Override protected String[] getServletMappings() { return new String[]{"/"}; } }
在這裏注意配置RootConfigClass爲WebAppConfig,ServletConfigClass爲WebMvcConfigmvc
package com.bdqn.lyrk.security.study.web; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @Configuration @ComponentScan @EnableWebMvc public class WebMvcConfig implements WebMvcConfigurer { /** * 建立視圖解析器 * @return */ @Bean public ViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setViewClass(JstlView.class); viewResolver.setPrefix("/WEB-INF/jsp/"); viewResolver.setSuffix(".jsp"); return viewResolver; } /** * 處理靜態資源 * @param registry */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/").setCachePeriod(60 * 2); } }
package com.bdqn.lyrk.security.study.web.controller; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.User; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @Controller public class LoginController { @PostMapping("/toIndex") public String index(ModelMap modelMap) { User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); modelMap.put("user", user); return "main/index"; } @GetMapping("/login") public String login() { return "login"; } }
login.jsp:app
<%-- Created by IntelliJ IDEA. User: chen.nie Date: 2018/6/8 Time: 上午9:49 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <!doctype html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Amaze UI Admin index Examples</title> <meta name="description" content="這是一個 index 頁面"> <meta name="keywords" content="index"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="renderer" content="webkit"> <meta http-equiv="Cache-Control" content="no-siteapp" /> <link rel="icon" type="image/png" href="assets/i/favicon.png"> <link rel="apple-touch-icon-precomposed" href="assets/i/app-icon72x72@2x.png"> <meta name="apple-mobile-web-app-title" content="Amaze UI" /> <link rel="stylesheet" href="${request.contextPath}/static/assets/css/amazeui.min.css" /> <link rel="stylesheet" href="${request.contextPath}/static/assets/css/admin.css"> <link rel="stylesheet" href="${request.contextPath}/static/assets/css/app.css"> </head> <body data-type="login"> <div class="am-g myapp-login"> <div class="myapp-login-logo-block tpl-login-max"> <div class="myapp-login-logo-text"> <div class="myapp-login-logo-text"> Amaze UI<span> Login</span> <i class="am-icon-skyatlas"></i> </div> </div> <div class="login-font"> <i>Log In </i> or <span> Sign Up</span> </div> <div class="am-u-sm-10 login-am-center"> <form class="am-form" action="/login" method="post"> <fieldset> <div class="am-form-group"> <input name="username" type="text" class="" id="doc-ipt-email-1" placeholder="輸入登陸名"> </div> <div class="am-form-group"> <input name="password" type="password" class="" id="doc-ipt-pwd-1" placeholder="設置個密碼吧"> </div> <p><button type="submit" class="am-btn am-btn-default">登陸</button></p> </fieldset> <input type="hidden" name="_csrf" value="${_csrf.token}" /> </form> </div> </div> </div> <script src="${request.contextPath}/static/assets/js/jquery.min.js"></script> <script src="${request.contextPath}/static/assets/js/amazeui.min.js"></script> <script src="${request.contextPath}/static/assets/js/app.js"></script> </body>
注意:1)表單屬性action爲httpSecurity的loginPage()配置地址
2)表單爲post方式提交
3)input的name屬性分別爲username,password表明用戶名,密碼
4)必須設置隱藏表單_csrf 若是不設置請http.csrf().ignoringAntMatchers()方法進行排除
<%-- Created by IntelliJ IDEA. User: chen.nie Date: 2018/6/8 Time: 上午9:56 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> 歡迎:${user.username} </body> </html>
在成功頁時打印出認證成功的用戶.
隨即當咱們訪問http://localhost:8080/toIndex時跳轉至登陸頁:
登陸成功時:
在實際應用中登陸頁可能要複雜的多,可能包括驗證碼或者其餘業務。另外用戶不可能都存在內存當中,關於更詳細的驗證問題,咱們會在下篇討論。