Repository: cxf-fediz Updated Branches: refs/heads/master 626e76831 -> a8c4d86f9
[FEDIZ-134] Initial prototype Project: http://git-wip-us.apache.org/repos/asf/cxf-fediz/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf-fediz/commit/a8c4d86f Tree: http://git-wip-us.apache.org/repos/asf/cxf-fediz/tree/a8c4d86f Diff: http://git-wip-us.apache.org/repos/asf/cxf-fediz/diff/a8c4d86f Branch: refs/heads/master Commit: a8c4d86f9b4fa776259eb5db788c9e2b146aeced Parents: 626e768 Author: Sergey Beryozkin <[email protected]> Authored: Tue Nov 3 16:36:34 2015 +0000 Committer: Sergey Beryozkin <[email protected]> Committed: Tue Nov 3 16:36:34 2015 +0000 ---------------------------------------------------------------------- services/oidc/pom.xml | 99 ++++++++++++ .../service/oidc/ClientRegistrationService.java | 106 +++++++++++++ .../service/oidc/FedizAccessTokenValidator.java | 63 ++++++++ .../service/oidc/LocalSamlTokenConverter.java | 39 +++++ .../fediz/service/oidc/OAuthDataManager.java | 158 +++++++++++++++++++ .../cxf/fediz/service/oidc/RegisterClient.java | 23 +++ .../fediz/service/oidc/SamlTokenConverter.java | 28 ++++ .../oidc/src/main/webapp/META-INF/context.xml | 22 +++ .../main/webapp/WEB-INF/applicationContext.xml | 88 +++++++++++ .../src/main/webapp/WEB-INF/views/consumers.jsp | 65 ++++++++ .../WEB-INF/views/oAuthAuthorizationData.jsp | 95 +++++++++++ .../webapp/WEB-INF/views/registerClient.jsp | 90 +++++++++++ services/oidc/src/main/webapp/WEB-INF/web.xml | 94 +++++++++++ 13 files changed, 970 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/a8c4d86f/services/oidc/pom.xml ---------------------------------------------------------------------- diff --git a/services/oidc/pom.xml b/services/oidc/pom.xml new file mode 100644 index 0000000..9f47256 --- /dev/null +++ b/services/oidc/pom.xml @@ -0,0 +1,99 @@ +<?xml version="1.0"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.cxf.fediz</groupId> + <artifactId>fediz</artifactId> + <version>1.3.0-SNAPSHOT</version> + <relativePath>../../pom.xml</relativePath> + </parent> + <artifactId>fediz-oidc</artifactId> + <name>Apache Fediz OIDC</name> + <packaging>war</packaging> + <properties> + <cxf.version>3.1.5-SNAPSHOT</cxf.version> + </properties> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>${junit.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <version>${servlet.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.cxf.fediz</groupId> + <artifactId>fediz-core</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-rs-security-sso-oidc</artifactId> + <version>${cxf.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-web</artifactId> + <version>${spring.version}</version> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + <version>${commons.lang.version}</version> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-war-plugin</artifactId> + <configuration> + <webResources> + <resource> + <directory>src/main/webapp</directory> + <filtering>true</filtering> + <includes> + <include>**/applicationContext.xml</include> + <include>**/web.xml</include> + </includes> + </resource> + <resource> + <directory>src/main/webapp</directory> + <filtering>false</filtering> + <excludes> + <exclude>**/applicationContext.xml</exclude> + <exclude>**/web.xml</exclude> + </excludes> + </resource> + </webResources> + </configuration> + </plugin> + </plugins> + <!-- Name of the generated WAR file --> + <finalName>fediz-oidc</finalName> + </build> +</project> http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/a8c4d86f/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/ClientRegistrationService.java ---------------------------------------------------------------------- diff --git a/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/ClientRegistrationService.java b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/ClientRegistrationService.java new file mode 100644 index 0000000..8d90635 --- /dev/null +++ b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/ClientRegistrationService.java @@ -0,0 +1,106 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.fediz.service.oidc; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.SecurityContext; + +import org.apache.cxf.common.util.Base64UrlUtility; +import org.apache.cxf.rs.security.oauth2.client.Consumer; +import org.apache.cxf.rs.security.oauth2.client.Consumers; +import org.apache.cxf.rs.security.oauth2.common.Client; +import org.apache.cxf.rt.security.crypto.CryptoUtils; + +@Path("/") +public class ClientRegistrationService { + + private Map<String, Map<String, Consumer>> registrations = + new ConcurrentHashMap<String, Map<String, Consumer>>(); + private OAuthDataManager manager; + @Context + private SecurityContext sc; + + @GET + @Produces(MediaType.TEXT_HTML) + @Path("/") + public RegisterClient registerStart() { + return new RegisterClient(); + } + + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.TEXT_HTML) + @Path("/register") + public Consumers registerForm(@FormParam("appName") String appName, + @FormParam("appDescription") String appDesc, + @FormParam("appType") String appType, + @FormParam("redirectURI") String redirectURI) { + String clientId = generateClientId(); + String clientSecret = + "confidential".equals(appType) ? generateClientSecret() : null; + + Client newClient = new Client(clientId, clientSecret, true, appName, null); + newClient.setApplicationDescription(appDesc); + newClient.setRedirectUris(Collections.singletonList(redirectURI)); + + return registerNewClient(newClient); + } + + protected String generateClientId() { + return Base64UrlUtility.encode(CryptoUtils.generateSecureRandomBytes(10)); + } + + protected String generateClientSecret() { + return Base64UrlUtility.encode(CryptoUtils.generateSecureRandomBytes(15)); + } + + private Consumers registerNewClient(Client newClient) { + manager.registerClient(newClient); + String userName = sc.getUserPrincipal().getName(); + Map<String, Consumer> userClientRegs = registrations.get(userName); + if (userClientRegs == null) { + userClientRegs = new HashMap<String, Consumer>(); + registrations.put(userName, userClientRegs); + } + Consumer c = new Consumer(newClient.getClientId(), newClient.getClientSecret()); + c.setDescription(newClient.getApplicationDescription()); + userClientRegs.put(newClient.getClientId(), c); + return new Consumers(new HashSet<Consumer>(userClientRegs.values())); + + } + + public void setDataProvider(OAuthDataManager m) { + this.manager = m; + } +} + http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/a8c4d86f/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/FedizAccessTokenValidator.java ---------------------------------------------------------------------- diff --git a/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/FedizAccessTokenValidator.java b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/FedizAccessTokenValidator.java new file mode 100644 index 0000000..76f0cfa --- /dev/null +++ b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/FedizAccessTokenValidator.java @@ -0,0 +1,63 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.fediz.service.oidc; + +import java.util.Collections; +import java.util.List; + +import javax.ws.rs.core.MultivaluedMap; + +import org.apache.cxf.jaxrs.ext.MessageContext; +import org.apache.cxf.rs.security.oauth2.common.AccessTokenValidation; +import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken; +import org.apache.cxf.rs.security.oauth2.provider.AccessTokenValidator; +import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException; +import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants; + +public class FedizAccessTokenValidator implements AccessTokenValidator { + + private OAuthDataManager dataProvider; + + @Override + public List<String> getSupportedAuthorizationSchemes() { + return Collections.singletonList(OAuthConstants.BEARER_AUTHORIZATION_SCHEME); + } + + @Override + public AccessTokenValidation validateAccessToken(MessageContext mc, String authScheme, String authSchemeData, + MultivaluedMap<String, String> extraProps) throws OAuthServiceException { + + // This is the access token used by a 3rd party client when accessing a REST service + ServerAccessToken token = dataProvider.getAccessToken(authSchemeData); + + String idToken = token.getSubject().getProperties().get("id_token"); + if (idToken != null) { + //TODO: validate the user behind this id_token is still a valid user ? + } + // Do some Fediz specific token validation ? + // and + // Let CXF do the core validation (is access token still valid, etc) + return new AccessTokenValidation(token); + } + + public void setDataProvider(OAuthDataManager dataProvider) { + this.dataProvider = dataProvider; + } + +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/a8c4d86f/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/LocalSamlTokenConverter.java ---------------------------------------------------------------------- diff --git a/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/LocalSamlTokenConverter.java b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/LocalSamlTokenConverter.java new file mode 100644 index 0000000..7a68081 --- /dev/null +++ b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/LocalSamlTokenConverter.java @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.fediz.service.oidc; + +import org.w3c.dom.Document; +import org.apache.cxf.rs.security.jose.jwt.JwtClaims; + +public class LocalSamlTokenConverter implements SamlTokenConverter { + + @Override + public JwtClaims convertToJwt(Document samlDoc, + String subjectName, + String audience) { + JwtClaims claims = new JwtClaims(); + claims.setSubject(subjectName); + claims.setAudience(audience); + claims.setIssuer("accounts.sixt.com"); + claims.setIssuedAt(System.currentTimeMillis() / 1000); + claims.setExpiryTime(System.currentTimeMillis() / 1000 + 60000); + return claims; + } + +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/a8c4d86f/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/OAuthDataManager.java ---------------------------------------------------------------------- diff --git a/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/OAuthDataManager.java b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/OAuthDataManager.java new file mode 100644 index 0000000..6a08465 --- /dev/null +++ b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/OAuthDataManager.java @@ -0,0 +1,158 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.fediz.service.oidc; + +import java.security.Principal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.cxf.fediz.core.FedizPrincipal; +import org.apache.cxf.jaxrs.ext.MessageContext; +import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactProducer; +import org.apache.cxf.rs.security.jose.jws.NoneJwsSignatureProvider; +import org.apache.cxf.rs.security.jose.jwt.JwtClaims; +import org.apache.cxf.rs.security.oauth2.common.Client; +import org.apache.cxf.rs.security.oauth2.common.OAuthPermission; +import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken; +import org.apache.cxf.rs.security.oauth2.grants.code.AbstractCodeDataProvider; +import org.apache.cxf.rs.security.oauth2.grants.code.ServerAuthorizationCodeGrant; +import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException; +import org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken; +import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants; + +public class OAuthDataManager extends AbstractCodeDataProvider { + + private static final OAuthPermission OPENID_PERMISSION; + private static final Map<String, OAuthPermission> PERMISSION_MAP; + + static { + PERMISSION_MAP = new HashMap<String, OAuthPermission>(); + OPENID_PERMISSION = new OAuthPermission("openid", "OIDC Authentication"); + OPENID_PERMISSION.setDefault(true); + PERMISSION_MAP.put("openid", OPENID_PERMISSION); + } + + private MessageContext messageContext; + private SamlTokenConverter tokenConverter = new LocalSamlTokenConverter(); + private Map<String, Client> clients = new ConcurrentHashMap<String, Client>(); + private Map<String, ServerAccessToken> accessTokens = new ConcurrentHashMap<String, ServerAccessToken>(); + private Map<String, RefreshToken> refreshTokens = new ConcurrentHashMap<String, RefreshToken>(); + private Map<String, ServerAuthorizationCodeGrant> codeGrants = + new ConcurrentHashMap<String, ServerAuthorizationCodeGrant>(); + + public void registerClient(Client c) { + clients.put(c.getClientId(), c); + } + + public Client getClient(String clientId) throws OAuthServiceException { + return clients.get(clientId); + } + + // Grants + @Override + protected void saveCodeGrant(ServerAuthorizationCodeGrant grant) { + Principal principal = messageContext.getSecurityContext().getUserPrincipal(); + + if (principal instanceof FedizPrincipal) { + grant.getSubject().getProperties().put("id_token", + getJoseIdToken((FedizPrincipal)principal, + grant.getClient().getClientId())); + } else { + throw new OAuthServiceException("Unsupported principal"); + } + + codeGrants.put(grant.getCode(), grant); + + } + + private String getJoseIdToken(FedizPrincipal principal, String clientId) { + JwtClaims jwtClaims = tokenConverter.convertToJwt(principal.getLoginToken().getOwnerDocument(), + principal.getName(), + clientId); + JwsJwtCompactProducer p = new JwsJwtCompactProducer(jwtClaims); + return p.signWith(new NoneJwsSignatureProvider()); + } + + @Override + public ServerAuthorizationCodeGrant removeCodeGrant(String code) throws OAuthServiceException { + return codeGrants.remove(code); + } + + // Access Tokens + @Override + protected void saveAccessToken(ServerAccessToken token) { + accessTokens.put(token.getTokenKey(), token); + } + + @Override + protected boolean revokeAccessToken(String tokenKey) { + return accessTokens.remove(tokenKey) != null; + } + + @Override + public ServerAccessToken getAccessToken(String tokenId) throws OAuthServiceException { + return accessTokens.get(tokenId); + } + + // Refresh Tokens + @Override + protected void saveRefreshToken(ServerAccessToken accessToken, RefreshToken refreshToken) { + refreshTokens.put(refreshToken.getTokenKey(), refreshToken); + } + + @Override + protected RefreshToken revokeRefreshToken(Client c, String tokenKey) { + return refreshTokens.remove(tokenKey); + } + + @Override + protected boolean isRefreshTokenSupported(List<String> theScopes) { + return theScopes.contains(OAuthConstants.REFRESH_TOKEN_SCOPE); + } + + // Scope to Permission conversion + @Override + public List<OAuthPermission> convertScopeToPermissions(Client client, List<String> scopes) + throws OAuthServiceException { + List<OAuthPermission> list = new ArrayList<OAuthPermission>(); + for (String scope : scopes) { + OAuthPermission permission = PERMISSION_MAP.get(scope); + if (permission == null) { + throw new OAuthServiceException("Unexpected scope: " + scope); + } + list.add(permission); + } + // Ensure the default permission is available + if (list.isEmpty()) { + list.add(OPENID_PERMISSION); + } + return list; + } + + public void setMessageContext(MessageContext messageContext) { + this.messageContext = messageContext; + } + + public void setTokenConverter(SamlTokenConverter tokenConverter) { + this.tokenConverter = tokenConverter; + } +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/a8c4d86f/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/RegisterClient.java ---------------------------------------------------------------------- diff --git a/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/RegisterClient.java b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/RegisterClient.java new file mode 100644 index 0000000..9a8c7a2 --- /dev/null +++ b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/RegisterClient.java @@ -0,0 +1,23 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.fediz.service.oidc; + +public class RegisterClient { + +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/a8c4d86f/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/SamlTokenConverter.java ---------------------------------------------------------------------- diff --git a/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/SamlTokenConverter.java b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/SamlTokenConverter.java new file mode 100644 index 0000000..24a5e2a --- /dev/null +++ b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/SamlTokenConverter.java @@ -0,0 +1,28 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.fediz.service.oidc; + +import org.w3c.dom.Document; +import org.apache.cxf.rs.security.jose.jwt.JwtClaims; + +public interface SamlTokenConverter { + JwtClaims convertToJwt(Document samlDoc, + String subjectName, + String audience); +} http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/a8c4d86f/services/oidc/src/main/webapp/META-INF/context.xml ---------------------------------------------------------------------- diff --git a/services/oidc/src/main/webapp/META-INF/context.xml b/services/oidc/src/main/webapp/META-INF/context.xml new file mode 100644 index 0000000..a789b58 --- /dev/null +++ b/services/oidc/src/main/webapp/META-INF/context.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<Context> + <Valve className="org.apache.cxf.fediz.tomcat7.FederationAuthenticator" configFile="conf/fediz_config.xml" /> +</Context> http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/a8c4d86f/services/oidc/src/main/webapp/WEB-INF/applicationContext.xml ---------------------------------------------------------------------- diff --git a/services/oidc/src/main/webapp/WEB-INF/applicationContext.xml b/services/oidc/src/main/webapp/WEB-INF/applicationContext.xml new file mode 100644 index 0000000..628eceb --- /dev/null +++ b/services/oidc/src/main/webapp/WEB-INF/applicationContext.xml @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:jaxrs="http://cxf.apache.org/jaxrs" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd + http://cxf.apache.org/jaxrs + http://cxf.apache.org/schemas/jaxrs.xsd"> + + <jaxrs:server address="/idp"> + <jaxrs:serviceBeans> + <bean id="oidcService" class="org.apache.cxf.rs.security.oidc.idp.OidcAuthorizationCodeService"> + <property name="dataProvider" ref="oauthProvider"/> + <property name="skipAuthorizationWithOidcScope" value="true"/> + </bean> + </jaxrs:serviceBeans> + <jaxrs:providers> + <ref bean="viewProvider"/> + </jaxrs:providers> + </jaxrs:server> + + <jaxrs:server address="/client"> + <jaxrs:serviceBeans> + <bean id="clientRegService" class="org.apache.cxf.fediz.service.oidc.ClientRegistrationService"> + <property name="dataProvider" ref="oauthProvider"/> + </bean> + </jaxrs:serviceBeans> + <jaxrs:providers> + <ref bean="viewProvider"/> + </jaxrs:providers> + </jaxrs:server> + + <bean id="viewProvider" class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider"> + <property name="useClassNames" value="true"/> + <property name="locationPrefix" value="/WEB-INF/views/"/> + <property name="beanName" value="data"/> + <property name="dispatcherName" value="jsp"/> + </bean> + + <bean id="idTokenFilter" class="org.apache.cxf.rs.security.oidc.idp.IdTokenResponseFilter"/> + + <bean id="accessTokenService" class="org.apache.cxf.rs.security.oauth2.services.AccessTokenService"> + <property name="dataProvider" ref="oauthProvider"/> + <property name="responseFilter" ref="idTokenFilter"/> + </bean> + <bean id="fedizTokenValidator" class="org.apache.cxf.fediz.service.oidc.FedizAccessTokenValidator"> + <property name="dataProvider" ref="oauthProvider"/> + </bean> + <bean id="accessTokenValidatorService" class="org.apache.cxf.rs.security.oauth2.services.AccessTokenValidatorService"> + <property name="tokenValidator" ref="fedizTokenValidator"/> + <!-- Setting this property allows RS to avoid authenticating with AS when RS + requests a token validation, should be avoided in the production + --> + <property name="blockUnauthorizedRequests" value="false"/> + </bean> + <jaxrs:server address="/oauth2Token"> + <jaxrs:serviceBeans> + <ref bean="accessTokenService"/> + <ref bean="accessTokenValidatorService"/> + </jaxrs:serviceBeans> + <jaxrs:providers> + <bean id="jsonProvider" class="org.apache.cxf.rs.security.oauth2.provider.OAuthJSONProvider"/> + </jaxrs:providers> + </jaxrs:server> + + <bean id="oauthProvider" class="org.apache.cxf.fediz.service.oidc.OAuthDataManager"/> + +</beans> + http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/a8c4d86f/services/oidc/src/main/webapp/WEB-INF/views/consumers.jsp ---------------------------------------------------------------------- diff --git a/services/oidc/src/main/webapp/WEB-INF/views/consumers.jsp b/services/oidc/src/main/webapp/WEB-INF/views/consumers.jsp new file mode 100644 index 0000000..21b77ac --- /dev/null +++ b/services/oidc/src/main/webapp/WEB-INF/views/consumers.jsp @@ -0,0 +1,65 @@ +<%@ page import="javax.servlet.http.HttpServletRequest, org.apache.cxf.rs.security.oauth2.client.Consumer, org.apache.cxf.rs.security.oauth2.client.Consumers" %> + +<% + Consumers regs = (Consumers)request.getAttribute("data"); + String basePath = request.getContextPath() + request.getServletPath(); + if (!basePath.endsWith("/")) { + basePath += "/"; + } +%> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>API Client Registration Confirmation</title> + <STYLE TYPE="text/css"> + <!-- + div.padded { + padding-left: 2em; + } + --> +</STYLE> +</head> +<body> +<div class="padded"> + +<h1>Registered API Clients</h1> +<em></em> +<br/> +<table border="1"> + <tr><th><big><big>Client Name</big></big></th><th><big><big>Client Identifier</big></big></th><th><big><big>Client Secret</big></big></th><th><big><big>PreAuthorized Token</big></big></th><th><big><big>PreAuthorized Code</big></big></th></tr> + <% + for (Consumer entry : regs.getConsumers()) { + %> + <tr> + <td><big><big><%= entry.getDescription() %></big></big></td> + <td><big><big><input type="text" name="clientId" readonly="readonly" value="<%= entry.getKey() %>"/></big></big></td> + <% + if (entry.getSecret() != null) { + %> + <td><big><big><%= entry.getSecret() %></big></big></td> + <% + } else { + %> + <td><big><big>Unavailable for public client</big></big></td> + <% + } + %> + </tr> + <% + } + %> + +</table> + +<br/> +<p> +<big><big> +</p> +<br/> +<p> +Back to <a href="<%= basePath %>client">Client Registration page</a> +</p> +</big></big> +</div> +</body> +</html> + http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/a8c4d86f/services/oidc/src/main/webapp/WEB-INF/views/oAuthAuthorizationData.jsp ---------------------------------------------------------------------- diff --git a/services/oidc/src/main/webapp/WEB-INF/views/oAuthAuthorizationData.jsp b/services/oidc/src/main/webapp/WEB-INF/views/oAuthAuthorizationData.jsp new file mode 100644 index 0000000..ca659c8 --- /dev/null +++ b/services/oidc/src/main/webapp/WEB-INF/views/oAuthAuthorizationData.jsp @@ -0,0 +1,95 @@ +<%@ page import="javax.servlet.http.HttpServletRequest,org.apache.cxf.rs.security.oauth2.common.OAuthAuthorizationData,org.apache.cxf.rs.security.oauth2.common.Permission" %> + +<% + OAuthAuthorizationData data = (OAuthAuthorizationData)request.getAttribute("data"); +%> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>Third Party Authorization Form</title> + <STYLE TYPE="text/css"> + <!-- + input,button {font-family:verdana, arial, helvetica, sans-serif;font-size:20px;line-height:40px;} + --> +</STYLE> +</head> +<body> +<title align="center">Third Party Authorization Form</title> +<table align="center"> + <tr align="center"> + <td> + + <form action="<%= data.getReplyTo() %>" method="POST"> + + <input type="hidden" name="client_id" + value="<%= data.getClientId() %>"/> + <input type="hidden" name="state" + value="<%= data.getState() %>"/> + <input type="hidden" name="scope" + value="<%= data.getProposedScope() %>"/> + <input type="hidden" name="redirect_uri" + value="<%= data.getRedirectUri() %>"/> + <input type="hidden" + name="<%= org.apache.cxf.rs.security.oauth2.utils.OAuthConstants + .SESSION_AUTHENTICITY_TOKEN %>" + value="<%= data.getAuthenticityToken() %>"/> + <p><big><big><big>Would you like to grant <%= data.getApplicationName() %><br/>(<%= data.getApplicationDescription() %>)</big></big></big> + + <br/><br/> + <img src="<%= data.getApplicationLogoUri() %>" alt="Application Logo" width="100" height="100"> + <br/></p> + <big><big>the following permissions:<big/></big> + <p/> + <table> + <% + for (Permission perm : data.getPermissions()) { + %> + <tr> + <td> + <input type="checkbox" + <% + if (perm.isDefault()) { + %> + disabled="disabled" + <% + } + %> + checked="checked" + name="<%= perm.getPermission()%>_status" + value="allow" + ><big><big><%= perm.getDescription() %></big></big></input> + <% + if (perm.isDefault()) { + %> + <input type="hidden" name="<%= perm.getPermission()%>_status" value="allow" /> + <% + } + %> + </td> + </tr> + <% + } + %> + </table> + <br/></p> + <button name="<%= org.apache.cxf.rs.security.oauth2.utils.OAuthConstants + .AUTHORIZATION_DECISION_KEY %>" + type="submit" + value="<%= org.apache.cxf.rs.security.oauth2.utils.OAuthConstants + .AUTHORIZATION_DECISION_ALLOW %>"> + OK + </button> + <button name="<%= org.apache.cxf.rs.security.oauth2.utils.OAuthConstants + .AUTHORIZATION_DECISION_KEY %>" + type="submit" + value="<%= org.apache.cxf.rs.security.oauth2.utils.OAuthConstants + .AUTHORIZATION_DECISION_DENY %>"> + No,thanks + </button> + + </form> + </td> + </tr> + </table> + +</body> +</html> http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/a8c4d86f/services/oidc/src/main/webapp/WEB-INF/views/registerClient.jsp ---------------------------------------------------------------------- diff --git a/services/oidc/src/main/webapp/WEB-INF/views/registerClient.jsp b/services/oidc/src/main/webapp/WEB-INF/views/registerClient.jsp new file mode 100644 index 0000000..cba8661 --- /dev/null +++ b/services/oidc/src/main/webapp/WEB-INF/views/registerClient.jsp @@ -0,0 +1,90 @@ +<%@ page import="javax.servlet.http.HttpServletRequest" %> +<% + String basePath = request.getContextPath() + request.getServletPath(); + if (!basePath.endsWith("/")) { + basePath += "/"; + } +%> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>Client Registration Form</title> + <STYLE TYPE="text/css"> + <!-- + input {font-family:verdana, arial, helvetica, sans-serif;font-size:20px;line-height:40px;} + H1 { text-align: center} + div.padded { + padding-left: 5em; + } + --> +</STYLE> +</head> +<body> +<H1>API Client Registration Form</H1> +<br/> +<div class="padded"> + + <form action="/fediz-oidc/client/register" + method="POST"> + <table> + <tr> + <td><big><big><big>API Client Name:</big></big></big></td> + <td> + <input type="text" name="appName" size="50" value="API Client"/> + </td> + </tr> + <tr> + <td colspan="2"> </td> + </tr> + <tr> + <td><big><big><big>API Client Description:</big></big></big></td> + <td> + <input type="text" size="50" name="appDescription" + value="API Service Client"/> + </td> + </tr> + <tr> + <td colspan="2"> </td> + </tr> + <tr> + <td><big><big><big>API Client Type:</big></big></big></td> + <td> + <select name="appType" size="50"> + <option value="confidential">Confidential</option> + <option value="public">Public</option> + </select> + </td> + </tr> + <tr> + <td colspan="2"> </td> + </tr> + <tr> + <td><big><big><big>Redirect URI:</big></big></big></td> + <td> + <input type="text" size="50" name="redirectURI" + value=""/> + </td> + </tr> + <tr> + <td> + + </td> + </tr> + </table> + <table align="center"> + <tr> + <td colspan="2"> + <input type="submit" value=" Register API Client "/> + </td> + </tr> + </table> + </form> +<br/> +<big><big> +<p> +Back to your account <a href="<%= basePath %>"> page</a> +</p> +</big></big> +</div> + +</body> +</html> http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/a8c4d86f/services/oidc/src/main/webapp/WEB-INF/web.xml ---------------------------------------------------------------------- diff --git a/services/oidc/src/main/webapp/WEB-INF/web.xml b/services/oidc/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..1cca8e0 --- /dev/null +++ b/services/oidc/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" + version="3.0" metadata-complete="true"> + + <description>WS Federation Spring Example</description> + <display-name>WS Federation Spring Example</display-name> + + <!-- Optional: Cache the security token in Thread Local Storage --> + <filter> + <filter-name>FederationFilter</filter-name> + <filter-class>org.apache.cxf.fediz.core.servlet.FederationFilter</filter-class> + </filter> + + <filter-mapping> + <filter-name>FederationFilter</filter-name> + <url-pattern>/idp/*</url-pattern> + </filter-mapping> + <filter-mapping> + <filter-name>FederationFilter</filter-name> + <url-pattern>/client/*</url-pattern> + </filter-mapping> + + <context-param> + <param-name>contextConfigLocation</param-name> + <param-value>/WEB-INF/applicationContext.xml</param-value> + </context-param> + + <listener> + <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> + </listener> + + <servlet> + <servlet-name>FederationServlet</servlet-name> + <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> + </servlet> + + <servlet-mapping> + <servlet-name>FederationServlet</servlet-name> + <url-pattern>/*</url-pattern> + </servlet-mapping> + <security-role> + <role-name>Manager</role-name> + </security-role> + <security-role> + <role-name>User</role-name> + </security-role> + <security-role> + <role-name>Admin</role-name> + </security-role> + <security-role> + <role-name>Authenticated</role-name> + </security-role> + <security-constraint> + <web-resource-collection> + <web-resource-name>Client Registration Protected Area</web-resource-name> + <url-pattern>/client/*</url-pattern> + </web-resource-collection> + <auth-constraint> + <role-name>*</role-name> + </auth-constraint> + </security-constraint> + <security-constraint> + <web-resource-collection> + <web-resource-name>User Protected Area</web-resource-name> + <url-pattern>/idp/*</url-pattern> + </web-resource-collection> + <auth-constraint> + <role-name>*</role-name> + </auth-constraint> + </security-constraint> + <login-config> + <auth-method>WSFED</auth-method> + <realm-name>WSFED</realm-name> + </login-config> +</web-app>
