spring-security

spring-security

Maven:
other dependency elements

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

由于Spring Boot提供Maven BOM来管理依赖版本,因此无需指定版本。如果您希望覆盖Spring Security版本,可以通过提供Maven属性来实现:

pom.xml中。

<spring-security.version>5.1.2.RELEASE</spring-security.version>

6.1 Hello Web安全Java配置

第一步是创建我们的Spring Security Java配置。该配置创建一个称为springSecurityFilterChain的Servlet过滤器,它负责应用程序中的所有安全性(保护应用程序URL,验证提交的用户名和密码,重定向到登录表单等)。您可以在下面找到Spring Security Java配置的最基本示例:

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.*;
import org.springframework.security.config.annotation.authentication.builders.*;
import org.springframework.security.config.annotation.web.configuration.*;

@EnableWebSecurity
public class WebSecurityConfig implements WebMvcConfigurer {

    @Bean
    public UserDetailsService userDetailsService() throws Exception {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withDefaultPasswordEncoder().username("user").password("password").roles("USER").build());
        return manager;
    }
}

这种配置确实没什么用,但它做了很多。您可以在下面找到以下功能的摘要:

要求对应用程序中的每个URL进行身份验证
为您生成登录表单
允许具有Username 用户和密码 密码的用户使用基于表单的身份验证进行身份验证
允许用户注销
CSRF攻击预防
会话固定保护
安全标头集成

用于安全请求的 HTTP严格传输安全性
X-Content-Type-Options集成
缓存控制(稍后可由应用程序覆盖以允许缓存静态资源)
X-XSS-Protection集成
X-Frame-Options集成有助于防止Clickjacking
与以下Servlet API方法集成

HttpServletRequest的#getRemoteUser()
HttpServletRequest.html#getUserPrincipal()
HttpServletRequest.html#的isUserInRole(java.lang.String中)
HttpServletRequest.html#login(java.lang.String,java.lang.String)
HttpServletRequest.html#注销()

6.1.1 AbstractSecurityWebApplicationInitializer

下一步是在战争中注册springSecurityFilterChain。这可以在Java配置中使用Spring在Servlet 3.0+环境中的WebApplicationInitializer支持来完成。毫不奇怪,Spring Security提供了一个基类AbstractSecurityWebApplicationInitializer,可确保springSecurityFilterChain为您注册。我们使用AbstractSecurityWebApplicationInitializer的方式取决于我们是否已经使用Spring或者Spring Security是我们应用程序中唯一的Spring组件。

6.1.2 没有现有Spring的AbstractSecurityWebApplicationInitializer

如果您不使用Spring或Spring MVC,则需要将WebSecurityConfig传入超类以确保获取配置。你可以在下面找到一个例子:

import org.springframework.security.web.context.*;

public class SecurityWebApplicationInitializer
    extends AbstractSecurityWebApplicationInitializer {

    public SecurityWebApplicationInitializer() {
        super(WebSecurityConfig.class);
    }
}

SecurityWebApplicationInitializer将执行以下操作:

自动为应用程序中的每个URL注册springSecurityFilterChain过滤器
添加一个加载WebSecurityConfig的ContextLoaderListener 。

6.1.3 使用Spring MVC的AbstractSecurityWebApplicationInitializer

如果我们在我们的应用程序的其他地方使用Spring,我们可能已经有WebApplicationInitializer正在加载我们的Spring配置。如果我们使用以前的配置,我们会收到错误。相反,我们应该使用现有的ApplicationContext注册Spring Security。例如,如果我们使用Spring MVC,我们的SecurityWebApplicationInitializer将如下所示:

import org.springframework.security.web.context.*;

public class SecurityWebApplicationInitializer
    extends AbstractSecurityWebApplicationInitializer {

}

这只会为应用程序中的每个URL注册springSecurityFilterChain过滤器。之后,我们将确保在我们现有的ApplicationInitializer中加载WebSecurityConfig。例如,如果我们使用Spring MVC,它将被添加到getRootConfigClasses()中

public class MvcWebApplicationInitializer extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { WebSecurityConfig.class };
    }

    // ... other overrides ...
}

6.2 HttpSecurity

到目前为止,我们的WebSecurityConfig仅包含有关如何验证用户身份的信息。Spring Security如何知道我们要求所有用户都经过身份验证?Spring Security如何知道我们想要支持基于表单的身份验证?原因是WebSecurityConfigurerAdapter在configure(HttpSecurity http)方法中提供了一个默认配置,如下所示:

protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .anyRequest().authenticated()
            .and()
        .formLogin()
            .and()
        .httpBasic();
}

上面的默认配置:

确保对我们的应用程序的任何请求都要求用户进行身份验证
允许用户使用基于表单的登录进行身份验证
允许用户使用HTTP基本身份验证进行身份验证
您会注意到此配置与XML命名空间配置非常相似:

<http>
    <intercept-url pattern="/**" access="authenticated"/>
    <form-login />
    <http-basic />
</http>

使用and()方法表示关闭XML标记的Java配置,它允许我们继续配置父标记。如果您阅读代码,它也是有道理的。我想配置授权请求并配置表单登录并配置HTTP基本身份验证。

6.3 Java配置和表单登录

当您被提示登录时,您可能想知道登录表单的来源,因为我们没有提及任何HTML文件或JSP。由于Spring Security的默认配置未明确设置登录页面的URL,因此Spring Security会根据启用的功能自动生成一个URL,并使用处理提交的登录的URL的标准值,默认值登录后用户将被发送到的目标URL,依此类推。

虽然自动生成的登录页面便于快速启动和运行,但大多数应用程序都希望提供自己的登录页面。为此,我们可以更新我们的配置,如下所示:

protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .anyRequest().authenticated()
            .and()
        .formLogin()
            .loginPage("/login") 1
            .permitAll();        2
}

1:更新的配置指定登录页面的位置。

2:我们必须授予所有用户(即未经身份验证的用户)访问我们的登录页面的权限。formLogin().permitAll()方法允许为与基于表单的登录相关联的所有URL授予对所有用户的访问权限。

6.4 授权请求

我们的示例仅要求用户进行身份验证,并且已针对应用程序中的每个URL进行了身份验证。我们可以通过向http.authorizeRequests()方法添加多个子项来指定网址的自定义要求。例如:

protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()                                                                1
            .antMatchers("/resources/**", "/signup", "/about").permitAll()                  2
            .antMatchers("/admin/**").hasRole("ADMIN")                                      3
            .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")            4
            .anyRequest().authenticated()                                                   5
            .and()
        // ...
        .formLogin();
}

1:http.authorizeRequests()方法有多个子项,每个匹配器按其声明的顺序进行考虑。

2:我们指定了任何用户都可以访问的多种URL模式。具体来说,如果URL以“/ resources /”开头,等于“/ signup”或等于“/ about”,则任何用户都可以访问请求。

3:任何以“/ admin /”开头的URL都将仅限于具有“ROLE_ADMIN”角色的用户。您会注意到,由于我们正在调用hasRole方法,因此我们不需要指定“ROLE_”前缀。

4:任何以“/ db /”开头的URL都要求用户同时拥有“ROLE_ADMIN”和“ROLE_DBA”。您会注意到,由于我们使用的是hasRole表达式,因此我们不需要指定“ROLE_”前缀。

五:任何尚未匹配的URL只需要对用户进行身份验证

6.5 处理注销

使用WebSecurityConfigurerAdapter时,会自动应用注销功能。默认情况下,访问URL /logout将通过以下方式记录用户:

使HTTP会话无效
清理已配置的任何RememberMe身份验证
清除SecurityContextHolder
重定向到/login?logout
但是,与配置登录功能类似,您还可以使用各种选项来进一步自定义注销要求:

protected void configure(HttpSecurity http) throws Exception {
    http
        .logout()                                                                1
            .logoutUrl("/my/logout")                                                 2
            .logoutSuccessUrl("/my/index")                                           3
            .logoutSuccessHandler(logoutSuccessHandler)                              4
            .invalidateHttpSession(true)                                             5
            .addLogoutHandler(logoutHandler)                                         6
            .deleteCookies(cookieNamesToClear)                                       7
            .and()
        ...
}

1:提供注销支持。使用WebSecurityConfigurerAdapter时会自动应用此选项。

2:触发注销的URL(默认为/logout)。如果启用了CSRF保护(默认),则该请求也必须是POST。有关更多信息,请参阅JavaDoc。

3:注销后重定向到的URL。默认值为/login?logout。有关更多信息,请参阅JavaDoc。

4:我们指定一个自定义LogoutSuccessHandler。如果指定了此项,则忽略logoutSuccessUrl()。有关更多信息,请参阅JavaDoc。
5:指定在注销时是否使HttpSession无效。默认情况下这是真的。配置SecurityContextLogoutHandler封面。有关更多信息,请参阅JavaDoc。

6:添加LogoutHandler。默认情况下,SecurityContextLogoutHandler被添加为最后一个LogoutHandler。

7:允许指定在注销成功时删除的cookie的名称。这是显式添加CookieClearingLogoutHandler的快捷方式。

[注意]
=当然也可以使用XML Namespace表示法配置注销。有关更多详细信息,请参阅Spring Security XML命名空间部分中的logout元素的文档。=

通常,为了自定义注销功能,您可以添加LogoutHandler和/或LogoutSuccessHandler实现。对于许多常见场景,这些处理程序在使用流畅的API时应用于幕后。

6.5.1 LogoutHandler

通常,LogoutHandler实现表示能够参与注销处理的类。预计将调用它们以进行必要的清理。因此,他们不应该抛出异常。提供了各种实现:

对PersistentTokenBasedRememberMeServices
TokenBasedRememberMeServices
CookieClearingLogoutHandler
CsrfLogoutHandler
SecurityContextLogoutHandler
有关详细信息,请参见第10.5.4节“记住我的接口和实现”。

而不是直接提供LogoutHandler实现,流畅的API还提供了快捷方式,提供了各自的LogoutHandler实现。例如,deleteCookies()允许指定在注销成功时删除的一个或多个cookie的名称。与添加CookieClearingLogoutHandler相比,这是一种捷径。

6.5.2 LogoutSuccessHandler

在LogoutFilter成功注销后调用LogoutSuccessHandler,以处理例如重定向或转发到适当的目的地。请注意,该接口几乎与LogoutHandler相同,但可能引发异常。

提供以下实现:

SimpleUrlLogoutSuccessHandler
HttpStatusReturningLogoutSuccessHandler
如上所述,您无需直接指定SimpleUrlLogoutSuccessHandler。相反,fluent API通过设置logoutSuccessUrl()来提供快捷方式。这将设置SimpleUrlLogoutSuccessHandler。发生注销后,提供的URL将重定向到。默认值为/login?logout。

在REST API类型场景中,HttpStatusReturningLogoutSuccessHandler可能很有趣。成功注销后,LogoutSuccessHandler允许您提供要返回的纯HTTP状态代码,而不是在成功注销时重定向到URL。如果未配置,则默认返回状态代码200。

6.5.3进一步注销相关参考

注销处理
测试注销
HttpServletRequest.logout()
第10.5.4节“记住我的接口和实现”
登录 CSRF警告部分
部分单点注销(CAS协议)
Spring Security XML命名空间部分中 的logout元素的文档

6.6 OAuth 2.0客户端

OAuth 2.0客户端功能为OAuth 2.0授权框架中定义的客户端角色提供支持。

可以使用以下主要功能:

授权代码授予
客户凭证授权
Servlet环境的WebClient扩展(用于发出受保护的资源请求)
HttpSecurity.oauth2Client()提供了许多用于自定义OAuth 2.0 Client的配置选项。以下代码显示了oauth2Client() DSL可用的完整配置选项:

@EnableWebSecurity
public class OAuth2ClientSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .oauth2Client()
                .clientRegistrationRepository(this.clientRegistrationRepository())
                .authorizedClientRepository(this.authorizedClientRepository())
                .authorizedClientService(this.authorizedClientService())
                .authorizationCodeGrant()
                    .authorizationRequestRepository(this.authorizationRequestRepository())
                    .authorizationRequestResolver(this.authorizationRequestResolver())
                    .accessTokenResponseClient(this.accessTokenResponseClient());
    }
}

以下部分详细介绍了每种可用的配置选项:

第6.6.1节“ClientRegistration”
第6.6.2节“ClientRegistrationRepository”
第6.6.3节“OAuth2AuthorizedClient”
第6.6.4节“OAuth2AuthorizedClientRepository / OAuth2AuthorizedClientService”
第6.6.5节“RegisteredOAuth2AuthorizedClient”
第6.6.6节“AuthorizationRequestRepository”
第6.6.7节“OAuth2AuthorizationRequestResolver”
第6.6.8节“OAuth2AccessTokenResponseClient”

6.6.1 ClientRegistration

ClientRegistration表示在OAuth 2.0或OpenID Connect 1.0提供程序中注册的客户端。

客户端注册保存信息,例如客户端ID,客户端密钥,授权授权类型,重定向URI,范围,授权URI,令牌URI和其他详细信息。

ClientRegistration及其属性定义如下:

public final class ClientRegistration {
    private String registrationId;  1
    private String clientId;    2
    private String clientSecret;    3
    private ClientAuthenticationMethod clientAuthenticationMethod;  4
    private AuthorizationGrantType authorizationGrantType;  5
    private String redirectUriTemplate; 6
    private Set<String> scopes; 7
    private ProviderDetails providerDetails;
    private String clientName;  8

    public class ProviderDetails {
        private String authorizationUri;    9
        private String tokenUri;    10
        private UserInfoEndpoint userInfoEndpoint;
        private String jwkSetUri;   11
        private Map<String, Object> configurationMetadata;  12

        public class UserInfoEndpoint {
            private String uri; 13
            private AuthenticationMethod authenticationMethod;  14
            private String userNameAttributeName;   15

        }
    }
}

1

registrationId:唯一标识ClientRegistration的ID。

2

clientId:客户端标识符。

3

clientSecret:客户机密。

4

clientAuthenticationMethod:用于使用Provider对客户端进行身份验证的方法。支持的值是基本和后期。

authorizationGrantType:OAuth 2.0授权框架定义了四种授权授权类型。支持的值是authorization_code,implicit和client_credentials。

6

redirectUriTemplate:客户端注册的重定向URI,授权服务器将最终用户的用户代理重定向到最终用户对客户端进行身份验证和授权访问之后。

7

scopes:客户在授权请求流程中请求的范围,例如openid,电子邮件或配置文件。

8

clientName:用于客户端的描述性名称。该名称可能在某些情况下使用,例如在自动生成的登录页面中显示客户端的名称时。

9

authorizationUri:授权服务器的授权端点URI。

10

tokenUri:授权服务器的令牌端点URI。

11

jwkSetUri:用于从授权服务器检索JSON Web密钥(JWK)集的URI ,其中包含用于验证ID 的JSON Web签名(JWS)的加密密钥令牌和可选的UserInfo响应。

12

configurationMetadata:OpenID提供程序配置信息。仅当配置了Spring Boot 2.x属性spring.security.oauth2.client.provider.[providerId].issuerUri时,才能使用此信息。

13

(userInfoEndpoint)uri:UserInfo端点URI,用于访问经过身份验证的最终用户的声明/属性。

14

(userInfoEndpoint)authenticationMethod:将访问令牌发送到UserInfo端点时使用的身份验证方法。支持的值是标题,表单和查询。

15:userNameAttributeName:UserInfo响应中返回的属性的名称,该属性引用最终用户的名称或标识符。
未完

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值