简单整合SpringBoot和SpringSecurity

最近SpringBoot2.0推出了,一直没去看,今天按照官网的guide跑了一个security的demo,确实感受到一些变化,基本都是语法方面的改动。

SpringBoot整合SpringSecurity的demo最详细的最全面的还是官网:https://spring.io/guides/gs/securing-web/

所需要的环境:jdk1.8+,springboot2.0

平台:ubuntu,meclipse

项目结构如下:

简单整合SpringBoot和SpringSecurity_第1张图片

首先是pom.xml文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0modelVersion>
  <groupId>SpringSecurityDemogroupId>
  <artifactId>SpringSecurityDemoartifactId>
  <version>0.0.1-SNAPSHOTversion>
  <packaging>warpackaging>
  <name>SpringSecurityDemoname>
  <description/>

  <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.0.0.RELEASEversion>
    parent>

  <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-thymeleafartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>org.springframework.securitygroupId>
            <artifactId>spring-security-testartifactId>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-securityartifactId>
        dependency>
    dependencies>

    <properties>
        <java.version>1.8java.version>
    properties>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-pluginartifactId>
        <version>2.3.2version>
        <configuration>
          <source>1.8source>
          <target>1.8target>
        configuration>
      plugin>
      <plugin>
        <artifactId>maven-war-pluginartifactId>
        <version>2.6version>
        <configuration>
          <failOnMissingWebXml>falsefailOnMissingWebXml>
        configuration>
      plugin>

      <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
      plugin>

    plugins>
  build>

  <repositories>
        <repository>
            <id>spring-releasesid>
            <name>Spring Releasesname>
            <url>https://repo.spring.io/libs-releaseurl>
        repository>
    repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-releasesid>
            <name>Spring Releasesname>
            <url>https://repo.spring.io/libs-releaseurl>
        pluginRepository>
    pluginRepositories>

project>

然后是几个简单页面:

hello.html:


<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Hello World!title>
    head>
    <body>
        <h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!h1>
        <form th:action="@{/logout}" method="post">
            <input type="submit" value="Sign Out"/>
        form>
    body>
html>

home.html:


<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Spring Security Exampletitle>
    head>
    <body>
        <h1>Welcome!h1>

        <p>Click <a th:href="@{/hello}">herea> to see a greeting.p>
    body>
html>

login.html:


<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Spring Security Example title>
    head>
    <body>
        <div th:if="${param.error}">
            Invalid username and password.
        div>
        <div th:if="${param.logout}">
            You have been logged out.
        div>
        <form th:action="@{/login}" method="post">
            <div><label> User Name : <input type="text" name="username"/> label>div>
            <div><label> Password: <input type="password" name="password"/> label>div>
            <div><input type="submit" value="Sign In"/>div>
        form>
    body>
html>

光看前端页面觉得平平无奇,可是后台逻辑的处理就与2.0以前的版本有区别了:

路由控制类:MvcConfig.java

package hello;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MvcConfig implements WebMvcConfigurer {

    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/home").setViewName("home");
        registry.addViewController("/").setViewName("home");
        registry.addViewController("/hello").setViewName("hello");
        registry.addViewController("/login").setViewName("login");
    }

}

以前的路由控制是直接在方法上面加注解指定路由,现在是统一在一个类中,有点类似于struts了,不过这也方便管理,addViewControllers()方法(在WebMvcConfigurer中覆盖相同名称的方法)添加了四个视图控制器。两个视图控制器引用名称为“home”的视图(在home.html中定义),另一个引用名为“hello”的视图(在hello.html中定义)。第四个视图控制器引用另一个名为“login”的视图。这样的设置是没有验证的,直接跳转,而无需登录。

security配置类:WebSecurityConfig.java

package hello;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/", "/home").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

    @Bean
    @Override
    public UserDetailsService userDetailsService() {
        UserDetails user =
             User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build();

        return new InMemoryUserDetailsManager(user);
    }
}

如果要防止未经授权的用户在“/hello”中查看hello页面。需要添加一个拦截,强制用户在看到该页面之前登录。

WebSecurityConfig类使用@EnableWebSecurity进行注释,以支持Spring Security的web安全支持,并提供Spring MVC集成。它还扩展了WebSecurityConfigurerAdapter通过覆盖方法来自定义设置一些配置。

configure(HttpSecurity)方法定义了哪些URL路径应该被保护,哪些不应该被保护。其中“/”和“/home”路径被配置为不需要任何身份验证。其他所有其他路径都必须经过身份验证。

当用户成功登录时,被重定向到先前请求的页面,该页面需要身份验证。有一个由loginPage()指定的自定义“/登录”页面,这个也是无需身份验证的。

userDetailsService()方法,设置一个存储在内存中的用户,并使用单个用户。该用户被赋予“user”的用户名,“password”的密码,以及“USER”的角色。

总结为一句话:Spring Security提供了一个过滤器,可以拦截该请求并对用户进行身份验证。

程序启动入口类:Application.java

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) throws Throwable {
        SpringApplication.run(Application.class, args);
    }

}

测试:

简单整合SpringBoot和SpringSecurity_第2张图片

简单整合SpringBoot和SpringSecurity_第3张图片

简单整合SpringBoot和SpringSecurity_第4张图片

你可能感兴趣的:(java,spring)