spring-security开始使用spring-security


备注

本节概述了spring-security是什么,以及开发人员为什么要使用它。

它还应该提到spring-security中的任何大型主题,并链接到相关主题。由于spring-security文档是新的,您可能需要创建这些相关主题的初始版本。

版本

发布日期
4.2.2 2017年3月2日
3.2.10 2016年12月22日
4.2.1 2016年12月21日
4.1.4 2016年12月21日
4.2.0 2016年11月10日

你好Spring Security

注1:在开始这个例子之前,你需要一些关于java servlet页面(JSP)Apache Maven的先验知识。

使用现有Web项目启动Web服务器(如Apache tomcat )或创建一个。

访问index.jsp

任何人都可以访问该页面,这是不安全的!


确保申请安全

  1. 更新Maven依赖项

将依赖项添加到pom.xml文件中

的pom.xml

<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-web</artifactId>
  <version>4.0.1.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-config</artifactId>
  <version>4.0.1.RELEASE</version>
</dependency>
 

注1:如果你之前没有在项目中使用“Spring”,那么就没有关于“spring-context”的依赖。此示例将使用带有“spring-context”的xml config。所以也要添加这个依赖项。

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>4.2.2.RELEASE</version>
</dependency>
 

注意2:如果您之前没有在项目中使用JSTL,则不依赖于此。此示例将在jsp页面中使用JSTL。所以也要添加这个依赖项。

<dependency>
  <groupId>org.glassfish.web</groupId>
  <artifactId>javax.servlet.jsp.jstl</artifactId>
  <version>1.2.1</version>
</dependency>
 

  1. 制作Spring安全配置文件

在“WEB-INF”文件夹中创建文件夹名称“spring”并生成security.xml文件。从下一个代码复制并粘贴。

WEB-INF /弹簧/ security.xml文件

<b:beans xmlns="http://www.springframework.org/schema/security"
         xmlns:b="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                             http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">

  <http />

  <user-service>
    <user name="stackoverflow" password="pwd" authorities="ROLE_USER" />
  </user-service>

</b:beans>
 

  1. 更新web.xml

更新“WEB-INF”文件夹中的web.xml

WEB-INF / web.xml文件

<filter>
  <filter-name>springSecurityFilterChain</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
 

注意:如果您之前没有在项目中使用“Spring”,则没有关于Spring上下文加载的配置。所以也要添加这个参数和监听器。

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
    /WEB-INF/spring/*.xml
  </param-value>
</context-param>

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
 

运行Secure Web应用程序

运行Web服务器并访问index.jsp后,您将看到spring security生成的默认登录页面。因为您未经过身份验证。

由spring security生成的登录页面

你可以登录

username : stackoverflow
password : pwd
 

注意: WEB-INF / spring / security.xml上的用户名和密码设置


显示用户名

在“Hello”之后添加jstl标签,打印用户名

的index.jsp

<h1>Hello <c:out value="${pageContext.request.remoteUser}" />!!</h1>
 

显示用户名


注销

的index.jsp

在“Hello用户名”之后添加表单,输入标签,从spring security提交生成的登出url / logout

<h1>Hello <c:out value="${pageContext.request.remoteUser}" />!!</h1>

<form action="/logout" method="post">
  <input type="submit" value="Log out" />
  <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
 

成功注销后,您将再次看到自动生成的登录页面。因为你现在没有经过身份验证。

注销按钮,注销成功

安装或设置

有关设置或安装弹簧安全性的详细说明。

Spring Securitiy保护REST API端点

pom.xml 添加以下条目。

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>3.1.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>3.1.0.RELEASE</version>
</dependency>
 

对于大于3.1的Spring版本很重要:

当您使用高于3.1的Spring版本并且没有为pom.xml spring-aopspring-jdbcspring-txspring-expressions 手动添加依赖项时,会出现org.springframework.security.filterChains Bean创建错误。

在Spring上下文中添加以下条目。我们想要保护两个REST端点(helloworld和goodbye)。根据Spring版本调整XSD版本。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:security="http://www.springframework.org/schema/security"
   xmlns:context="http://www.springframework.org/schema/context"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
                       http://www.springframework.org/schema/security
                       http://www.springframework.org/schema/security/spring-security-3.1.xsd">
                               
    <security:http auto-config='true' create-session="never">
        <security:intercept-url pattern="/helloworld/**" access="ROLE_USER" />
        <security:intercept-url pattern="/goodbye/**" access="ROLE_ADMIN" />
        <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
        <security:http-basic />
    </security:http>

    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <security:user name="username1" password="password1"
                    authorities="ROLE_USER" />
                <security:user name="username2" password="password2"
                    authorities="ROLE_ADMIN" />
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
</beans>
 

web.xml 添加以下条目。

<!-- Spring security-->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:security-context.xml</param-value>
</context-param>
 

Spring-Security使用spring-boot和JDBC身份验证

假设您想要阻止未经授权的用户访问该页面,那么您必须通过授权访问来阻止他们。我们可以通过使用spring-security来实现这一点,spring-security通过保护所有HTTP端点来提供基本身份验证。为此,您需要为项目添加spring-security依赖项,在maven中我们可以将依赖项添加为:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
 

这是一个安全配置,可确保只有经过身份验证的用户才能访问。

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
DataSource datasource;

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .anyRequest()
            .fullyAuthenticated()
            .and()
        .formLogin()
            .loginPage("/login")
            .failureUrl("/login?error")
            .permitAll()
            .and()
        .logout()
            .logoutUrl("/logout")
            .logoutSuccessUrl("/login?logout")
            .permitAll()
            .and()
        .csrf();
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.jdbcAuthentication().dataSource(datasource).passwordEncoder(passwordEncoder());
}

@Bean
public PasswordEncoder passwordEncoder() {
    PasswordEncoder encoder = new BCryptPasswordEncoder();
    return encoder;
}
}
 
组态描述
@Configuration 表示Spring IoC容器可以将该类用作bean定义的源。
@Order (SecurityProperties.ACCESS_OVERRIDE_ORDER) 覆盖访问规则而不更改任何其他自动配置的功能。较低的值具有较高的优先级
WebSecurityConfigurerAdapter SecurityConfig 类扩展并覆盖其几个方法,以设置安全配置的一些细节。
@Autowired of DataSource 提供工厂以连接到物理数据源。
configure(HttpSecurity) 重写方法定义应该保护哪些URL路径,哪些不应该保护。
.authorizeRequests().anyRequest() .fullyAuthenticated() 表示要对我们的应用程序的所有请求进行身份验证。
.formLogin() 配置基于表单的登录
.loginPage("/login").failureUrl("/login?error").permitAll() 指定登录页面的位置,并允许所有用户访问该页面。
.logout().logoutUrl("/logout") .logoutSuccessUrl("/login?logout").permitAll() 注销后重定向到的URL。默认为/ login?logout。
.csrf() 用于防止跨站点请求伪造,启用CSRF保护(默认)。
configure(AuthenticationManagerBuilder){} 重写方法,用于定义用户的身份验证方式。
.jdbcAuthentication().dataSource(datasource) 表示我们正在使用JDBC身份验证
.passwordEncoder(passwordEncoder()) 表示我们正在使用密码编码器来编码我们的密码。 (创建一个bean来返回密码Encoder的选择,我们在这种情况下使用BCrypt)

请注意,我们尚未配置任何要使用的表名或任何查询,这是因为默认情况下spring security会查找下表:

create table users (   
  username varchar(50) not null primary key,
  password varchar(255) not null,
  enabled boolean not null) ;

create table authorities (
  username varchar(50) not null,
  authority varchar(50) not null,
  foreign key (username) references users (username),
  unique index authorities_idx_1 (username, authority));
 

将以下行插入上表:

INSERT INTO authorities(username,authority) 
VALUES ('user', 'ROLE_ADMIN');

INSERT INTO users(username,password,enabled)
VALUES('user', '$2a$10$JvqOtJaDys0yoXPX9w47YOqu9wZr/PkN1dJqjG9HHAzMyu9EV1R4m', '1');
 

在我们的情况下, 用户名user密码也是user 与BCrypt算法加密

最后,在application.properties中配置数据源以使用spring boot:

spring.datasource.url = jdbc:mysql://localhost:3306/spring
spring.datasource.username = root
spring.datasource.password = Welcome123
 

注意:创建并配置登录控制器并将其映射到路径/login 并将登录页面指向此控制器