java jwt 单点登录_基于JWT实现SSO单点登录

本文介绍了如何使用Java和JWT实现SSO单点登录的详细步骤。通过创建一个认证服务器和两个客户端应用,阐述了OAuth2的授权码流程,以及在WebSecurityConfig和AuthorizationServerConfig中的配置。用户在认证服务器登录后,通过JWT令牌在多个应用间实现免登录切换。
摘要由CSDN通过智能技术生成

一、基于JWT实现SSO单点登录原理

1、什么是单点登录

所谓单点登录就是有多个应用部署在不同的服务器上,只需登录一次就可以互相访问不同服务器上的资源。

2、单点登录流程

79f62e047c1b68f6510e86c553b54944.png

当一个访问请求发给应用A,如果这个请求需要登录以后才能访问,那么应用A就会向认证服务器请求授权,这时候就把用户引导到认证服务器上。用户在认证服务器上完成认证并授权。认证授权完成后,认证服务器返回给应用A一个授权码,应用A携带授权码到认证服务器请求令牌,认证服务器返回应用A一个JWT,应用A解析JWT里面的信息,完成登录。这是一个标准的OAuth2的授权码流程。

走完认证流程后,给出去的JWT实际上里面包含的就是当前用户在认证服务器上登录以后用户的认证信息,应用A解析JWT后,自己生成一个经过认证的Authentication放到它的SpringSecurity和SecurityContext里面。

当访问应用服务器B的时候,同样引导用户去认证服务器请求授权(不需要登录),用户授权可以用登录的信息去访问应用B,后面同样是授权码流程,返回JWT给应用B。两个应用返回不同的JWT,但是解析出的信息是一样的。

二、实现单点登录

1、父工程(sso-demo)

1)pom.xml

org.springframework.boot

spring-boot-dependencies

2.0.4.RELEASE

pom

import

org.springframework.security.oauth.boot

spring-security-oauth2-autoconfigure

2.1.3.RELEASE

org.springframework.security

spring-security-jwt

1.0.10.RELEASE

2、认证服务(sso-server)

1)pom.xml

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-security

org.springframework.security.oauth.boot

spring-security-oauth2-autoconfigure

org.springframework.security

spring-security-jwt

2)application.properties

server.port = 9999server.servlet.context-path = /server

3)WebSecurityConfig.java

@EnableWebSecurity

@Configurationpublic class WebSecurityConfig extendsWebSecurityConfigurerAdapter{

@Overrideprotected void configure(HttpSecurity http) throwsException {

http.httpBasic().and().csrf().disable();

}

@BeanpublicPasswordEncoder passwordEncoder() {return newBCryptPasswordEncoder();

}

}

4)MyUserDetailsService.java

@Componentpublic class MyUserDetailsService implementsUserDetailsService{

@AutowiredprivatePasswordEncoder passwordEncoder;

@Overridepublic UserDetails loadUserByUsername(String username) throwsUsernameNotFoundException {

System.out.println("登录用户名:"+username);

String password= passwordEncoder.encode("123456");return new User(username,password,true,true,true,true,

AuthorityUtils.commaSeparatedStringToAuthorityList("all"));

}

}

5)SsoAuthorizationServerConfig.java

@Configuration

@EnableAuthorizationServerpublic class SsoAuthorizationServerConfig extendsAuthorizationServerConfigurerAdapter {

@AutowiredprivatePasswordEncoder passwordEncoder;

@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throwsException {

clients.inMemory()

.withClient("appclient_1").secret(passwordEncoder.encode("client1_123456"))

.authorizedGrantTypes("authorization_code","refresh_token")

.scopes("all")

.redirectUris("http://127.0.0.1:8080/client1/login")

.and()

.withClient("appclient_2").secret(passwordEncoder.encode("client2_123456"))

.authorizedGrantTypes("authorization_code","refresh_token")

.scopes("all")

.redirectUris("http://127.0.0.1:8060/client2/login");

}

@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throwsException {

endpoints.tokenStore(jwtTokenStore()).accessTokenConverter(jwtAccessTokenConverter());

}

@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throwsException {

security.tokenKeyAccess("isAuthenticated()");//访问tokenKey(秘钥shxiang)的时候需要身份认证

}

@BeanpublicTokenStore jwtTokenStore() {return newJwtTokenStore(jwtAccessTokenConverter());

}

@BeanpublicJwtAccessTokenConverter jwtAccessTokenConverter() {

JwtAccessTokenConverter accessTokenConverter= newJwtAccessTokenConverter();

accessTokenConverter.setSigningKey("shxiang");//设置秘钥

returnaccessTokenConverter;

}

}

6)SsoServerApplication.java

@SpringBootApplicationpublic classSsoServerApplication {public static voidmain(String[] args) {

SpringApplication.run(SsoServerApplication.class, args);

}

}

3、应用1(sso-client1)

1)pom.xml,同上

2)application.properties

security.oauth2.client.client-id =appclient_1

security.oauth2.client.client-secret =client1_123456

security.oauth2.client.user-authorization-uri = http://127.0.0.1:9999/server/oauth/authorize

security.oauth2.client.access-token-uri = http://127.0.0.1:9999/server/oauth/token

security.oauth2.resource.jwt.key-uri = http://127.0.0.1:9999/server/oauth/token_key

server.port=8080server.servlet.context-path =/client1

3)index.html

SSO Client1

SSO Demo Client1

访问Client2

4)SsoClient1Application.java

@SpringBootApplication

@RestController

@EnableOAuth2Ssopublic classSsoClient1Application {public static voidmain(String[] args) {

SpringApplication.run(SsoClient1Application.class, args);

}

@GetMapping("/user")publicAuthentication user(Authentication user) {returnuser;

}

}

4、应用2(sso-client2)

1)pom.xml,同上

2)application.properties,类比应用1修改

3)index.html,类比应用1修改

4)SsoClient2Application.java,同上

5、测试

1)浏览器输入:127.0.0.1:8080/client1/index.html

3b4e89039c1e30a6c063e58f08a3dad2.png

2)用户名随便输入,密码输入123456

e4c80f019438a6a110a1eb04292b2be7.png

3)点击Authorize

0aec9e148c8e25495006c3cde1384515.png

4)点击超级链接访问Client2

7ccb3c50da9fc8367339e5b0d28cc26a.png

5)点击Authorize

d3f3102bef3ede827257a7755d029dcc.png

认证成功,后面点击两个超级链接可以任意访问,无需登录 、无需点击Authorize。

注意:

2)实现跳过授权,登录后直接访问,修改如下代码:

25ecec79ed026ab73d053050480f474c.png

3)表单登录与httpBasic登录,修改WebSecurityConfig.java中configure方法

httpBasic登录:http.httpBasic().and().csrf().disable();

表单登录:http.formLogin().and().authorizeRequests().anyRequest().authenticated();

4)重点:浏览器访问要用127.0.0.1不要用localhost。要设置应用路径server.servlet.context-path =/xxxx,不能直接到端口号。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值