001/* 002 * Copyright 2025 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.mobileapp.action; 017 018import java.text.ParseException; 019import java.util.Map; 020 021import org.apache.cocoon.environment.Request; 022 023import org.ametys.core.authentication.CredentialProvider; 024import org.ametys.core.user.UserIdentity; 025import org.ametys.core.user.directory.UserDirectory; 026import org.ametys.core.user.population.UserPopulation; 027import org.ametys.plugins.extrausermgt.authentication.oidc.OIDCBasedCredentialProvider; 028 029import com.nimbusds.jose.JOSEException; 030import com.nimbusds.jose.JWSAlgorithm; 031import com.nimbusds.jose.proc.BadJOSEException; 032import com.nimbusds.jwt.JWT; 033import com.nimbusds.jwt.JWTParser; 034import com.nimbusds.oauth2.sdk.id.ClientID; 035import com.nimbusds.oauth2.sdk.id.Issuer; 036import com.nimbusds.openid.connect.sdk.claims.IDTokenClaimsSet; 037import com.nimbusds.openid.connect.sdk.validators.IDTokenValidator; 038 039/** 040 * Action exchanging an OIDC access token for an Ametys mobile app token. 041 */ 042public class GetTokenFromOIDCAction extends AbstractGetTokenAction 043{ 044 @Override 045 protected UserIdentity tryConnect(Map<String, Object> params, Request request, String context, UserPopulation userPopulation, CredentialProvider credentialProvider, int credentialProviderIndex) 046 { 047 if (credentialProvider instanceof OIDCBasedCredentialProvider oidcCredentialProvider) 048 { 049 try 050 { 051 String idToken = (String) getParameter("idToken", params, request); 052 053 JWT token = JWTParser.parse(idToken); 054 IDTokenValidator validator = new IDTokenValidator(new Issuer(oidcCredentialProvider.getIssuer()), 055 new ClientID(oidcCredentialProvider.getClientId()), 056 JWSAlgorithm.RS256, 057 oidcCredentialProvider.getJwkSetURL()); 058 IDTokenClaimsSet claims = validator.validate(token, null); 059 060 String login = claims.getStringClaim("preferred_username"); 061 062 for (UserDirectory userDirectory : userPopulation.getUserDirectories()) 063 { 064 if (userDirectory.getStoredUser(login) != null) 065 { 066 return new UserIdentity(login, userPopulation.getId()); 067 } 068 } 069 } 070 catch (ParseException | BadJOSEException | JOSEException e) 071 { 072 getLogger().error("Impossible to validate id token on population '" + userPopulation.getId() + "' using credential provider at position '" + credentialProviderIndex + "'", e); 073 } 074 } 075 076 return null; 077 } 078}