java oauth2 severlet_Spring Security Oauth2 单点登录案例实现和执行流程剖析

本文详细介绍了如何使用Spring Security OAuth2 实现单点登录功能,包括认证服务器配置、安全配置、客户端配置及执行流程。通过案例展示了整合SpringBoot、Spring Security OAuth2的SSO系统,涉及内存方式的用户认证、授权码授权类型和资源服务器配置。
摘要由CSDN通过智能技术生成

在线演示

用户名:admin 密码:admin

Spring Security Oauth2

OAuth是一个关于授权的开放网络标准,在全世界得到的广泛的应用,目前是2.0的版本。OAuth2在“客户端”与“服务提供商”之间,设置了一个授权层(authorization layer)。“客户端”不能直接登录“服务提供商”,只能登录授权层,以此将用户与客户端分离。“客户端”登录需要获取OAuth提供的令牌,否则将提示认证失败而导致客户端无法访问服务。关于OAuth2这里就不多作介绍了,网上资料详尽。下面我们实现一个 整合 SpringBoot 、Spring Security OAuth2 来实现单点登录功能的案例并对执行流程进行详细的剖析。

案例实现

项目介绍

这个单点登录系统包括下面几个模块:

spring-oauth-parent : 父模块,管理打包

spring-oauth-server : 认证服务端、资源服务端(端口:8881)

spring-oauth-client  : 单点登录客户端示例(端口:8882)

spring-oauth-client2: 单点登录客户端示例(端口:8883)

当通过任意客户端访问资源服务器受保护的接口时,会跳转到认证服务器的统一登录界面,要求登录,登录之后,在登录有效时间内任意客户端都无需再登录。

认证服务端

添加依赖

主要是添加 spring-security-oauth2 依赖。

pom.xml

4.0.0

spring-oauth-server

spring-oauth-server

war

com.louis

spring-oauth-parent

1.0.0-SNAPSHOT

org.springframework.boot

spring-boot-starter-web

org.springframework.security.oauth

spring-security-oauth2

${oauth.version}

org.springframework.boot

spring-boot-starter-freemarker

配置文件

配置文件内容如下。

application.yml

server:

port: 8881servlet:

context-path: /auth

启动类

启动类添加 @EnableResourceServer 注解,表示作为资源服务器。

OAuthServerApplication.java

packagecom.louis.spring.oauth.server;

importorg.springframework.boot.SpringApplication;

importorg.springframework.boot.autoconfigure.SpringBootApplication;

importorg.springframework.boot.web.servlet.support.SpringBootServletInitializer;

importorg.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;

@SpringBootApplication

@EnableResourceServer

public class OAuthServerApplication extendsSpringBootServletInitializer {

public static voidmain(String[] args) {

SpringApplication.run(OAuthServerApplication.class, args);

}

}

认证服务配置

添加认证服务器配置,这里采用内存方式获取,其他方式获取在这里定制即可。

OAuthServerConfig.java

packagecom.louis.spring.oauth.server.config;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.context.annotation.Configuration;importorg.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;importorg.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;importorg.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;importorg.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;importorg.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;

@Configuration

@EnableAuthorizationServerpublic class OAuthServerConfig extendsAuthorizationServerConfigurerAdapter {

@AutowiredprivateBCryptPasswordEncoder passwordEncoder;

@Overridepublic void configure(final AuthorizationServerSecurityConfigurer oauthServer) throwsException {

oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");

}

@Overridepublic void configure(final ClientDetailsServiceConfigurer clients) throwsException {

clients.inMemory()

.withClient("SampleClientId") //clientId, 可以类比为用户名

.secret(passwordEncoder.encode("secret")) //secret, 可以类比为密码

.authorizedGrantTypes("authorization_code") //授权类型,这里选择授权码

.scopes("user_info") //授权范围

.autoApprove(true) //自动认证

.redirectUris("http://localhost:8882/login","http://localhost:8883/login") //认证成功重定向URL

.accessTokenValiditySeconds(10); //超时时间,10s

}

}

安全配置

Spring Security 安全配置。在安全配置类里我们配置了:

1. 配置请求URL的访问策略。

2. 自定义了同一认证登录页面URL。

3. 配置用户名密码信息从内存中创建并获取。

SecurityConfig.java

packagecom.louis.spring.oauth.server.config;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.core.annotation.Order;importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;importorg.springframework.security.config.annotation.web.builders.HttpSecurity;importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;importorg.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration

@Order(1)public class SecurityConfig extendsWebSecurityConfigurerAdapter {

@Overrideprotected void configure(HttpSecurity http) throwsException {

http.requestMatchers()

.antMatchers("/login")

.antMatchers("/oauth/authorize")

.and()

.authorizeRequests()

.anyRequest().authenticated()

.and()

.formLogin().loginPage("/login").permitAll() //自定义登录页面,这里配置了 loginPage, 就会通过 LoginController 的 login 接口加载登录页面

.and().csrf().disable();

}

@Overrideprotected void configure(AuthenticationManagerBuilder auth) throwsException {//配置用户名密码,这里采用内存方式,生产环境需要从数据库获取

auth.inMemoryAuthentication()

.withUser("admin")

.password(passwordEncoder().encode("123"))

.roles("USER");

}

@BeanpublicBCryptPasswordEncoder passwordEncoder(){return newBCryptPasswordEncoder();

}

}

接口提供

这里提供了一个自定义的登录接口,用于跳转到自定义的同一认证登录页面。

LoginController.java

packagecom.louis.spring.oauth.server.controller;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.GetMapping;

@Controllerpublic classLoginController {/*** 自定义登录页面

*@return

*/@GetMapping("/login")publicString login() {return "login";

}

}

登录页面放置在 resources/templates 下,需要在登录时提交 pos t表单到 auth/login。

login.ftl

Insert title here

newVue({

el :'#app',

data : {

loading:false,

username:'admin',

password:'123'},

methods : {

}

})

border-radius: 5px;-moz-border-radius: 5px;

background-clip: padding-box;

margin: 100px auto;

width: 320px;

padding: 35px 35px 15px 35px;

background: #fff;

border: 1px solid #eaeaea;

box-shadow: 0 025px #cac6c6;

}

.title {

margin: 0px auto 20px auto;

text-align: center;

color: #505458;

}

这里提供了一个受保护的接口,用于获取用户信息,客户端访问这个接口的时候要求登录认证。

UserController.java

packagecom.louis.spring.oauth.server.controller;importjava.security.Principal;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;

@RestControllerpublic classUserController {/*** 资源服务器提供的受保护接口

*@paramprincipal

*@return

*/@RequestMapping("/user")publicPrincipal user(Principal principal) {

System.out.println(principal);returnprincipal;

}

}

客户端实现

添加依赖

主要添加 Spring Security 依赖,另外因为 Spring Boot 2.0 之后代码的合并, 需要添加 spring-security-oauth2-autoconfigure ,才能使用 @EnableOAuth2Sso 注解。

pom.xml

4.0.0

spring-oauth-client

spring-oauth-client

war

com.louis

spring-oauth-parent

1.0.0-SNAPSHOT

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-security

org.springframework.security.oauth.boot

spring-security-oauth2-autoconfigure

${oauth-auto.version}

org.springframework.boot

spring-boot-starter-thymeleaf

org.thymeleaf.extras

thymeleaf-extras-springsecurity4

启动类

启动类需要添加 RequestContextListener,用于监听HTTP请求事件。

OAuthClientApplication.java

packagecom.louis.spring.oauth.client;

importorg.springframework.boot.SpringApplication;

importorg.springframework.boot.autoconfigure.SpringBootApplication;

importorg.springframework.boot.web.servlet.support.SpringBootServletInitializer;

importorg.springframework.context.annotation.Bean;

importorg.springframework.web.context.request.RequestContextListener;

@SpringBootApplication

public class OAuthClientApplication extendsSpringBootServletInitializer {

@Bean

publicRequestContextListener requestContextListener() {

return newRequestContextListener();

}

public static voidmain(String[] args) {

SpringApplication.run(OAuthClientApplication.class, args);

}

}

安全配置

添加安全配置类,添加 @EnableOAuth2Sso 注解支持单点登录。

OAuthClientSecurityConfig.java

packagecom.louis.spring.oauth.client.config;importorg.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;importorg.springframework.context.annotation.Configuration;importorg.springframework.security.config.annotation.web.builders.HttpSecurity;importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableOAuth2Sso

@Configurationpublic class OAuthClientSecurityConfig extendsWebSecurityConfigurerAdapter {

@Overridepublic void configure(HttpSecurity http) throwsException {

http.csrf().disable()

.antMatcher("/**")

.aut

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值