接口地址(官网)
可以使用http://gateway.zlt2000.cn/访问接口
权限接口
权限校验有两个步骤:授权和认证
除了OAuth2.0默认的四种授权方式,另外自定义实现了三种,分别是验证码授权、手机号、openId授权方式
因此,请求是否认证成功,需要通过js原生方法btoa()对”client_id:client_secret”进行base64的转码,添加到请求头的Authorization参数中
web端默认使用client_id=webApp,client_secret=webApp
grant_type的类型:
- 密码模式:password
- 授权码模式:authorization_code
- 手机号授权:mobile_password
- 验证码授权:password_code
- openId授权:openId
- 使用aouth2.0密码模式获取token
http://gateway.zlt2000.cn/api-uaa/oauth/token?grant_type=password&username=admin&password=admin
获取到token就可以使用接口文档请求接口了
登录成功调用获取用户信息和权限信息的接口,通过请求api-user/menus/current动态生成左侧菜单
SSO实现
OAuth2.0默认实现
@EnableOAuth2Sso + uaa授权中心 + Oauth授权码模式 实现了基于session的实现
自动通过认证过滤器实现了授权码认证
自定义授权码 + OAuth2.0实现
- 没有实现对登录的拦截,前端通过是否存在token判断登录状态,通过用户名密码登录,调用oauth/authorize?clientId=xxx获取code
- 增加了后端的API服务,通过api服务封装了授权码获取token的接口
- 前端记录访问地址,认证成功后重定向访问的地址
基于OIDC实现
OIDC协议(id_token) + OAuth2.0 + JWT(jwt格式封装access_token和id_token) + 非对称加密(解析id_token)
接口请求
自定义认证处理器和过滤器
自定义token的解析和获取方式(headers/params)
@Bean SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { //认证处理器 ReactiveAuthenticationManager customAuthenticationManager = new CustomAuthenticationManager(tokenStore); JsonAuthenticationEntryPoint entryPoint = new JsonAuthenticationEntryPoint(); //token转换器 ServerBearerTokenAuthenticationConverter tokenAuthenticationConverter = new ServerBearerTokenAuthenticationConverter(); tokenAuthenticationConverter.setAllowUriQueryParameter(true); //oauth2认证过滤器 AuthenticationWebFilter oauth2Filter = new AuthenticationWebFilter(customAuthenticationManager); oauth2Filter.setServerAuthenticationConverter(tokenAuthenticationConverter); oauth2Filter.setAuthenticationFailureHandler(new ServerAuthenticationEntryPointFailureHandler(entryPoint)); oauth2Filter.setAuthenticationSuccessHandler(new Oauth2AuthSuccessHandler()); http.addFilterAt(oauth2Filter, SecurityWebFiltersOrder.AUTHENTICATION); ServerHttpSecurity.AuthorizeExchangeSpec authorizeExchange = http.authorizeExchange(); if (securityProperties.getAuth().getHttpUrls().length > 0) { authorizeExchange.pathMatchers(securityProperties.getAuth().getHttpUrls()).authenticated(); } if (securityProperties.getIgnore().getUrls().length > 0) { authorizeExchange.pathMatchers(securityProperties.getIgnore().getUrls()).permitAll(); } authorizeExchange .pathMatchers(HttpMethod.OPTIONS).permitAll() .anyExchange() .access(permissionAuthManager) .and() .exceptionHandling() .accessDeniedHandler(new JsonAccessDeniedHandler()) .authenticationEntryPoint(entryPoint) .and() .headers() .frameOptions() .disable() .and() .httpBasic().disable() .csrf().disable(); return http.build(); }
private String token(ServerHttpRequest request) { String authorizationHeaderToken = this.resolveFromAuthorizationHeader(request.getHeaders()); String parameterToken = (String)request.getQueryParams().getFirst("access_token"); if (authorizationHeaderToken != null) { if (parameterToken != null) { BearerTokenError error = BearerTokenErrors.invalidRequest("Found multiple bearer tokens in the request"); throw new OAuth2AuthenticationException(error); } else { return authorizationHeaderToken; } } else { return parameterToken != null && this.isParameterTokenSupportedForRequest(request) ? parameterToken : null; } }
单点登出