【笔记】Spring Security Oauth2
模式
身份认证系统oauth2的四种模式
- 授权码模式 【第三方Web服务器端应用与第三方原生App】【采用】
- 简化模式 【第三方单页面应用】
- 密码模式 【第一方单页应用与第一方原生App】【采用】
- 客户端模式 【没有用户参与的,完全信任的服务器端服务】
需求
项目系统需要类似微信类似开发平台,让第三方能够接入进来正常的访问
使用
Oauth2回调地址设置。配置能够让授权码模式的运用主动权掌握到自己手里,根据第三方不同项目实际情况设置不同的回调
源码
DefaultRedirectResolver
org.springframework.security.oauth2.provider.endpoint.DefaultRedirectResolver源码:
/**
* Grant types that are permitted to have a redirect uri.
* 重定向解析程序的默认实现
* @param redirectGrantTypes the redirect grant types to set
*/
public void setRedirectGrantTypes(Collection<String> redirectGrantTypes) {
this.redirectGrantTypes = new HashSet<String>(redirectGrantTypes);
}
public String resolveRedirect(String requestedRedirect, ClientDetails client) throws OAuth2Exception {
Set<String> authorizedGrantTypes = client.getAuthorizedGrantTypes();
if (authorizedGrantTypes.isEmpty()) {
throw new InvalidGrantException("A client must have at least one authorized grant type.");
}
if (!containsRedirectGrantType(authorizedGrantTypes)) {
throw new InvalidGrantException(
"A redirect_uri can only be used by implicit or authorization_code grant types.");
}
Set<String> registeredRedirectUris = client.getRegisteredRedirectUri();
if (registeredRedirectUris == null || registeredRedirectUris.isEmpty()) {
throw new InvalidRequestException("At least one redirect_uri must be registered with the client.");
}
return obtainMatchingRedirect(registeredRedirectUris, requestedRedirect);
}
对重定向路径进行解析,如果不进行设置默认就是当前路径,譬如:当你访问security进行犿控制的路径http://example.com,跳转到oauth2的登录首页,点前页面指的就是http://example.com。方法来判断客户端的设置回调地址和服务端的回调地址是否一致,如下:
/**
* Attempt to match one of the registered URIs to the that of the requested one.
* 尝试将其中一个已注册的URI与所请求的URI进行匹配。
* @param redirectUris the set of the registered URIs to try and find a match. This cannot be null or empty.
* @param requestedRedirect the URI used as part of the request
* @return the matching URI
* @throws RedirectMismatchException if no match was found
*/
private String obtainMatchingRedirect(Set<String> redirectUris, String requestedRedirect) {
Assert.notEmpty(redirectUris, "Redirect URIs cannot be empty");
if (redirectUris.size() == 1 && requestedRedirect == null) {
return redirectUris.iterator().next();
}
for (String redirectUri : redirectUris) {
if (requestedRedirect != null && redirectMatches(requestedRedirect, redirectUri)) {
return requestedRedirect;
}
}
throw new RedirectMismatchException("Invalid redirect: " + requestedRedirect
+ " does not match one of the registered values.");
}
AbstractRedirectResourceDetails
重定向资源详细信息
package org.springframework.security.oauth2.client.token.grant.redirect;
import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.client.token.AccessTokenRequest;
import org.springframework.security.oauth2.client.token.DefaultAccessTokenRequest;
/**
* @author Dave Syer
*/
public abstract class AbstractRedirectResourceDetails extends BaseOAuth2ProtectedResourceDetails {
private String preEstablishedRedirectUri;
private String userAuthorizationUri;
private boolean useCurrentUri = true;
/**
* Flag to signal that the current URI (if set) in the request should be used in preference to the pre-established
* redirect URI.
*
* @param useCurrentUri the flag value to set (default true)
*/
public void setUseCurrentUri(boolean useCurrentUri) {
this.useCurrentUri = useCurrentUri;
}
/**
* Flag to signal that the current URI (if set) in the request should be used in preference to the pre-established
* redirect URI.
*
* @return the flag value
*/
public boolean isUseCurrentUri() {
return useCurrentUri;
}
/**
* The URI to which the user is to be redirected to authorize an access token.
*
* @return The URI to which the user is to be redirected to authorize an access token.
*/
public String getUserAuthorizationUri() {
return userAuthorizationUri;
}
/**
* The URI to which the user is to be redirected to authorize an access token.
*
* @param userAuthorizationUri The URI to which the user is to be redirected to authorize an access token.
*/
public void setUserAuthorizationUri(String userAuthorizationUri) {
this.userAuthorizationUri = userAuthorizationUri;
}
/**
* The redirect URI that has been pre-established with the server. If present, the redirect URI will be omitted from
* the user authorization request because the server doesn't need to know it.
*
* @return The redirect URI that has been pre-established with the server.
*/
public String getPreEstablishedRedirectUri() {
return preEstablishedRedirectUri;
}
/**
* The redirect URI that has been pre-established with the server. If present, the redirect URI will be omitted from
* the user authorization request because the server doesn't need to know it.
*
* @param preEstablishedRedirectUri The redirect URI that has been pre-established with the server.
*/
public void setPreEstablishedRedirectUri(String preEstablishedRedirectUri) {
this.preEstablishedRedirectUri = preEstablishedRedirectUri;
}
/**
* Extract a redirect uri from the resource and/or the current request.
*
* @param request the current {@link DefaultAccessTokenRequest}
* @return a redirect uri if one can be established
*/
public String getRedirectUri(AccessTokenRequest request) {
String redirectUri = request.getFirst("redirect_uri");
if (redirectUri == null && request.getCurrentUri() != null && useCurrentUri) {
redirectUri = request.getCurrentUri();
}
if (redirectUri == null && getPreEstablishedRedirectUri() != null) {
// Override the redirect_uri if it is pre-registered
redirectUri = getPreEstablishedRedirectUri();
}
return redirectUri;
}
}
Get请求
http://localhost:3000/oauth/authorize?response_type=code&client_id=test&redirect_uri=http://example.com&scope=all
输入账号密码后,成功跳转到http://example.com
参考:
OAuth 2.0
https://oauth.net/2/
Spring Security Oauth2系列(七)
https://blog.****.net/sinat_24798023/article/details/80537179
OAuth2.0协议入门(一):OAuth2.0协议的基本概念以及使用授权码模式(authorization code)实现百度账号登录
https://www.zifangsky.cn/1309.html