• SpringSecurity学习之快速上手


      互联网项目中,安全与权限控制是不可回避的问题,为了解决这一些列问题,许多安全框架应运而生了。这些框架旨在帮我们解决公用的安全问题,让我们的程序更加健壮,从而让程序员全身心投入到业务开发当中。那么SpringSecurity出自于大名鼎鼎的Spring家族,同时能与SpringBoot,SpringCloud无缝集成,它也是业界流行的安全框架之一。

    一、SpringSecurity的准备工作

    注意:本示例是基于注解的springmvc构建,SpringBoot的版本对应的是2.0.3.REALEASE。Spring版本5.0.7REALEASE,SpringSecurity的版本是5.0.5

    首先添加SpringSecurity的依赖:

    compile('org.springframework.boot:spring-boot-starter-security')

    紧接着按照如下目录规范创建

    app包下主要为Root WebApplicationContext提供配置,而web包下主要是为servlet WebApplicationContext提供相关配置,这种方式更符合WebApplicationContext的层次化规范,同时也方便管理配置

    二、实现app包下的配置

    2.1、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.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的安全配置和最基本的认证配置等,其中在该代码里设置静态资源 登录页 和登录成功需要跳转的页面不用认证,另外基于内存设置了用户admin

      另外:loginPage()里的值即为跳转页面的路径又为处理登录验证的路径。当get请求时为前者而post请求时为后者

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

    三、实现WebMvc的配置

    3.1、初始化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为WebMvcConfig

    3.2、创建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.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.1、登录页

    login.jsp:

    <%--
      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.2、 登录成功页

    <%--
      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时跳转至登录页:

    登录成功时:

    在实际应用中登录页可能要复杂的多,可能包括验证码或者其他业务。另外用户不可能都存在内存当中,关于更详细的验证问题,我们会在下篇讨论。

  • 相关阅读:
    六大关系整理
    pthread_create多线程执行顺序诡异现象
    WinForm中 事件 委托 多线程的应用
    伪ajax上传文件
    Webx小应用的实现整理与分析
    IL反编译的实用工具
    MVC4+WebApi+Redis Session共享练习(上)
    虚拟化平台cloudstack新版本的调试
    【c++】指针参数是如何传递内存的
    NPinyin 中文转换拼音代码
  • 原文地址:https://www.cnblogs.com/niechen/p/9154711.html
Copyright © 2020-2023  润新知