我创建了一个简单的授权服务器,但无法对其进行配置。
localhost:9999/client
并重定向到localhost:8080/login
(按预期方式)。localhost:9999/client
(按预期方式),但Hello, null
代替Hello, user
。但是,如果我直接转到localhost:8080/me
,我会{"name":"user"}
。如何检索Hello, user
?
授权服务器
@RestController
@EnableAuthorizationServer
@SpringBootApplication
public class Application extends WebSecurityConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@GetMapping({ "/user", "/me" })
public Map<String, String> user(Principal principal) {
return Collections.singletonMap("name", principal == null ? "null" : principal.getName());
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("user").authorities(AuthorityUtils.NO_AUTHORITIES);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin();
}
}
应用程序的属性
security:
oauth2:
client:
client-id: clientid
client-secret: clientsecret
scope: read,write
auto-approve-scopes: '.*'
客户端
@Configuration
@EnableAutoConfiguration
@EnableOAuth2Sso
@RestController
public class Client {
@GetMapping("/")
public String home(Principal principal) {
return "Hello, " + principal.getName();
}
public static void main(String[] args) {
new SpringApplicationBuilder(Client.class)
.properties("spring.config.name=client").run(args);
}
}
客户的属性
server:
port: 9999
context-path: /client
security:
oauth2:
client:
client-id: clientid
client-secret: clientsecret
access-token-uri: http://localhost:8080/oauth/token
user-authorization-uri: http://localhost:8080/oauth/authorize
resource:
user-info-uri: http://localhost:8080/me
更新
我完成所有工作后都下载了a tutorial,但它只有ssoFilter,仅适用于OAuth2身份验证。我只想用loginForm
配置它
我还在GitHub上分享了一个临时的example。我认为用它来查找问题会更容易。
答案 0 :(得分:1)
有不同的端口 9999 8080 这会在从其他域请求资源时导致跨源 HTTP请求,或端口,而不是第一个资源本身所服务的端口。
的详细信息官方春季网站上有一个很好的例子Enabling Cross Origin Requests for a RESTful Web Service
我建议您只需通过实施Filter界面即可在您的应用上进行CORS过滤。
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
public CorsFilter() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*"); //for production add only origins which should be allowed to access now for demo purposes this accepts all.
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); //i would reduce this method list if not all methods used this is added just for demo purposes
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void destroy() {
}
}
如果您使用的是春季启动应用程序,请确保包含新扫描程序在组件扫描中创建的。
如果您使用'web.xml'进行配置: 然后添加过滤器 选项 A 在servlet上添加映射 选项 B 为所有应用添加过滤器:<filter>
<filter-name>CORS</filter-name>
<filter-class>com.mycompany.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CORS</filter-name>
<servlet-name>MyServlet</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>CORS</filter-name>
<url-pattern>/*</url-pattern> <!--this will add cors on all apps-->
</filter-mapping>
答案 1 :(得分:0)
用户详细信息由org.springframework.cloud.security.oauth2.resource.UserInfoTokenServices
加载,因此值得在其中添加断点以查看它从您/我的端点获取的内容。
此类仅提取基本用户详细信息,实际上是查看设置ROLE_USER的硬编码角色的代码,因此建议您创建自己的详细信息以设置OAuth2Authentication
正确的为用户。
答案 2 :(得分:0)
稍微改变了你的代码,它对我来说是本地的。
@EnableOAuth2Client
@RestController
@EnableAuthorizationServer
@SpringBootApplication
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class Application extends WebSecurityConfigurerAdapter {
@Autowired
OAuth2ClientContext oauth2ClientContext;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@GetMapping({"/user", "/me"})
public Map<String, String> user(Principal principal) {
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
return Collections.singletonMap("name", principal == null ? "null" : principal.getName());
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("user").authorities(AuthorityUtils.NO_AUTHORITIES);
}
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http.antMatcher("/me").authorizeRequests().anyRequest().authenticated();
// @formatter:on
}
}
@Bean
public FilterRegistrationBean oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(filter);
registration.setOrder(-100);
return registration;
}
private Filter authFilter(ClientResources client, String path) {
OAuth2ClientAuthenticationProcessingFilter filter = new OAuth2ClientAuthenticationProcessingFilter(
path);
OAuth2RestTemplate template = new OAuth2RestTemplate(client.getClient(), oauth2ClientContext);
filter.setRestTemplate(template);
UserInfoTokenServices tokenServices = new UserInfoTokenServices(
client.getResource().getUserInfoUri(), client.getClient().getClientId());
tokenServices.setRestTemplate(template);
filter.setTokenServices(tokenServices);
return filter;
}
}
class ClientResources {
@NestedConfigurationProperty
private AuthorizationCodeResourceDetails client = new AuthorizationCodeResourceDetails();
@NestedConfigurationProperty
private ResourceServerProperties resource = new ResourceServerProperties();
public AuthorizationCodeResourceDetails getClient() {
return client;
}
public ResourceServerProperties getResource() {
return resource;
}
}
您需要注册authenticationTokenFilter,无需注册ssoFilter。
答案 3 :(得分:-1)
由于您的auth服务器和客户端都是从同一主机(localhost
)提供的,因此您的Web浏览器可能会混淆哪个http端点属于哪个http cookie。
尝试将其中一个指定为127.0.0.1
,将另一个指定为localhost
,以便您的浏览器将http Cookie与其正确的终结点相关联。