Closed JuHarm89 closed 9 years ago
For zuul you can extend com.netflix.zuul.ZuulFilter
to implement the redirection logic easily.
Override run()
method and start with
List<Pair<String, String>> responseHeaders = com.netflix.zuul.context.RequestContext.getCurrentContext().getZuulResponseHeaders();
Try these dependencies in you pom.xml
:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
</dependency>
<dependency>
<groupId>io.oasp.java.modules</groupId>
<artifactId>oasp4j-logging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
For versioning use BOMs:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>1.0.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.oasp.java</groupId>
<artifactId>oasp4j-bom</artifactId>
<version>1.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Can be configured via application.properties
or application.yml
.
See also org.springframework.cloud.netflix.zuul.ZuulProxyConfiguration
.
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
Example:
zuul.routes.oasp.path = /oasp/**
zuul.routes.oasp.url = http://localhost:8081/oasp
In General:
zuul.routes.<app>.path = /<app>/**
zuul.routes.<app>.url = http[s]://<host>:<port>/<app>
In the example above the portal would proxy a request on path /oasp/index.html
to http://localhost:8081/oasp/index.html and feed the result of that to the initial requester.
Hey Jörg, thanks for your Input. We already setup a Proxy with Spring Boot and Zuul and the proxy-part works fine. A bit tricky seems to be be how to get the JWT. Right now I am a bit confused whether it is possible to use the OpenAM JEE Policy Agent or Spring-cloud-security (@EnableOAuth2Sso) for this purpose. Another question would be: Doesn't the JWT need to be stored by the JS Client somehow (e.g. localstorage) and send with each request?
To make OpenAM issue JWT it needs to be configured as OpenID Provider (as it seems). So right now I can get a valid JWT from OpenAM as OpenID provider, but the Integration with the Policy Agent seems to be a little bit tricky, especially the Installation of the policy Agent on the embedded Tomcat of Spring Boot. Furthermore i am not sure if the JEE Policy Agent is the right choice for our needs, because normally policy agents are used on the app server itself and i didnt find any documentation about how to relay a JWT from a policy Agent to the Server running the application. OpenIG seems to be the solution here (having a own reverse Proxy build in) or we could maybe use Spring Cloud Security together with the ZuulProxy as API Gateway and make some customization on the Spring OAuth SSO Configuration to integrate it with OpenAM. What are your thoughts on that?
My thoughts about this are to decouple the JWT token generation from the AM generally. Just use what ever is easy as "protocol" or "contract" between portal and AM for auth (e.g. SAML). In the portal after auth simply generate JWT yourself and manually add it to the header of the zuul proxy request. You can cache the JWT in the session if exp claim fits to session timeout what should be suggested.
For me it worked like this:
@Named
public class OAuth2BearerHeaderFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 10;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
MyAuthentication authentication = MyAuthentication.get();
// authentication = (MyAuthentication ) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
ctx.addZuulRequestHeader(HttpHeaders.AUTHORIZATION,
OAuth2AccessToken.BEARER_TYPE + " " + authentication.getSecurityToken());
return null;
}
}
Within your implementation of AuthenticationProvider
you only need to create the instance of MyAuthentication
(probably name it AccessAuthentication
or OaspAuthentication
) containing the RSA-Signed token. Therefore I use Jackson to create the JWT-Content as JSON from a simple Map<String, String>
:
String jsonClaim = this.objectMapper.writeValueAsString(map); Jwt token = JwtHelper.encode(jsonClaim, this.signer); String securityToken = token.getEncoded();
That's about it...
Setup an application with Spring Boot and configure it as Reverse Proxy (Project Zuul) with Spring Cloud Netflix (http://cloud.spring.io/spring-cloud-netflix/spring-cloud-netflix.html). Additionally exploring OAuth2 capabilities of Spring Cloud Security for Oauth2 SSO with Bearer Tokens