SpringSecurity學習之快速上手

  互聯網項目中,安全與權限控制是不可迴避的問題,爲了解決這一些列問題,許多安全框架應運而生了。這些框架旨在幫咱們解決公用的安全問題,讓咱們的程序更加健壯,從而讓程序員全身心投入到業務開發當中。那麼SpringSecurity出自於大名鼎鼎的Spring家族,同時能與SpringBoot,SpringCloud無縫集成,它也是業界流行的安全框架之一。css

1、SpringSecurity的準備工做

注意:本示例是基於註解的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的層次化規範,同時也方便管理配置程序員

 

2、實現app包下的配置

2.一、WebSecurityInitializer

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 {
}
View Code

2.二、WebSecurityConfig

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"));
    }
}
View Code

  該類主要是設置安全配置注意使用@EnableWebSecruity註解,咱們能夠在這裏設置Http的安全配置和最基本的認證配置等,其中在該代碼裏設置靜態資源 登陸頁 和登陸成功須要跳轉的頁面不用認證,另外基於內存設置了用戶adminweb

  另外:loginPage()裏的值即爲跳轉頁面的路徑又爲處理登陸驗證的路徑。當get請求時爲前者而post請求時爲後者spring

 

2.三、WebAppConfig

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();
    }
}
View Code

 

3、實現WebMvc的配置

3.一、初始化DispatcherServlet配置

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[]{"/"};
    }
}
View Code

在這裏注意配置RootConfigClass爲WebAppConfig,ServletConfigClass爲WebMvcConfigmvc

3.二、建立WebMvcConfig

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);
    }
}
View Code

3.三、建立Controller

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";
    }
}
View Code

 

4、頁面設置

4.一、登陸頁

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

注意:1)表單屬性action爲httpSecurity的loginPage()配置地址

   2)表單爲post方式提交

   3)input的name屬性分別爲username,password表明用戶名,密碼

   4)必須設置隱藏表單_csrf 若是不設置請http.csrf().ignoringAntMatchers()方法進行排除

 

4.二、 登陸成功頁

<%--
  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>
View Code

  在成功頁時打印出認證成功的用戶.

 

隨即當咱們訪問http://localhost:8080/toIndex時跳轉至登陸頁:

登陸成功時:

 

在實際應用中登陸頁可能要複雜的多,可能包括驗證碼或者其餘業務。另外用戶不可能都存在內存當中,關於更詳細的驗證問題,咱們會在下篇討論。

相關文章
相關標籤/搜索