在spring security中授权服务器的默认匹配规则是全路径匹配
详见源码 AuthorizationEndpoint.authorize
redirectResolver.resolveRedirect(redirectUriParameter, client);
@RequestMapping(value = "/oauth/authorize")
public ModelAndView authorize(Map<String, Object> model, @RequestParam Map<String, String> parameters,
//...省略
// The resolved redirect URI is either the redirect_uri from the parameters or the one from
// clientDetails. Either way we need to store it on the AuthorizationRequest.
String redirectUriParameter = authorizationRequest.getRequestParameters().get(OAuth2Utils.REDIRECT_URI);
String resolvedRedirect = redirectResolver.resolveRedirect(redirectUriParameter, client);
if (!StringUtils.hasText(resolvedRedirect)) {
throw new RedirectMismatchException(
"A redirectUri must be either supplied or preconfigured in the ClientDetails");
}
authorizationRequest.setRedirectUri(resolvedRedirect);
//...省略
}
默认匹配解析器 DefaultRedirectResolver
protected boolean redirectMatches(String requestedRedirect, String redirectUri) {
UriComponents requestedRedirectUri = UriComponentsBuilder.fromUriString(requestedRedirect).build();
String requestedRedirectUriScheme = (requestedRedirectUri.getScheme() != null ? requestedRedirectUri.getScheme() : "");
String requestedRedirectUriHost = (requestedRedirectUri.getHost() != null ? requestedRedirectUri.getHost() : "");
String requestedRedirectUriPath = (requestedRedirectUri.getPath() != null ? requestedRedirectUri.getPath() : "");
UriComponents registeredRedirectUri = UriComponentsBuilder.fromUriString(redirectUri).build();
String registeredRedirectUriScheme = (registeredRedirectUri.getScheme() != null ? registeredRedirectUri.getScheme() : "");
String registeredRedirectUriHost = (registeredRedirectUri.getHost() != null ? registeredRedirectUri.getHost() : "");
String registeredRedirectUriPath = (registeredRedirectUri.getPath() != null ? registeredRedirectUri.getPath() : "");
boolean portsMatch = this.matchPorts ? (registeredRedirectUri.getPort() == requestedRedirectUri.getPort()) : true;
return registeredRedirectUriScheme.equals(requestedRedirectUriScheme) &&
hostMatches(registeredRedirectUriHost, requestedRedirectUriHost) &&
portsMatch &&
// Ensure exact path matching
registeredRedirectUriPath.equals(StringUtils.cleanPath(requestedRedirectUriPath));
}
从最后registeredRedirectUriPath.equals(StringUtils.cleanPath(requestedRedirectUriPath));这句看出来默认的规则就是全路径匹配。
我们如果需要自定义就直接写个类实现RedirectResolver接口 直接copy这个类 定义一个 antMatcher然后替换这个判断就好了
修改如下:
protected boolean redirectMatches(String requestedRedirect, String redirectUri) {
UriComponents requestedRedirectUri = UriComponentsBuilder.fromUriString(requestedRedirect).build();
String requestedRedirectUriScheme = (requestedRedirectUri.getScheme() != null ? requestedRedirectUri.getScheme() : "");
String requestedRedirectUriHost = (requestedRedirectUri.getHost() != null ? requestedRedirectUri.getHost() : "");
String requestedRedirectUriPath = (requestedRedirectUri.getPath() != null ? requestedRedirectUri.getPath() : "");
UriComponents registeredRedirectUri = UriComponentsBuilder.fromUriString(redirectUri).build();
String registeredRedirectUriScheme = (registeredRedirectUri.getScheme() != null ? registeredRedirectUri.getScheme() : "");
String registeredRedirectUriHost = (registeredRedirectUri.getHost() != null ? registeredRedirectUri.getHost() : "");
String registeredRedirectUriPath = (registeredRedirectUri.getPath() != null ? registeredRedirectUri.getPath() : "");
boolean portsMatch = this.matchPorts ? (registeredRedirectUri.getPort() == requestedRedirectUri.getPort()) : true;
return registeredRedirectUriScheme.equals(requestedRedirectUriScheme) &&
hostMatches(registeredRedirectUriHost, requestedRedirectUriHost) &&
portsMatch &&
// Ensure exact path matching
pathMatcher(registeredRedirectUriPath,StringUtils.cleanPath(requestedRedirectUriPath));
}
private boolean pathMatcher(String requestPath,String registeredPath){
AntPathMatcher antPathMatcher = new AntPathMatcher();
return antPathMatcher.matchStart(registeredPath, requestPath);
}
这样即可与github 等站点的匹配规则一致