Lemonldap-NG-Portal

 view release on metacpan or  search on metacpan

lib/Lemonldap/NG/Portal/Issuer/OpenIDConnect.pm  view on Meta::CPAN

    # Check client_id
    my $client_id = $oidc_request->{'client_id'};
    $self->logger->debug("Request from client id $client_id");

    # Verify that client_id is registered in configuration
    my $rp = $self->getRP($client_id);

    unless ($rp) {
        return $self->_failAuthorize(
            $req,
            msg => (
                    "No registered Relying Party found with"
                  . " client_id $client_id"
            ),
            res => PE_UNKNOWNPARTNER
        );
    }
    else {
        $self->logger->debug("Client id $client_id matches RP $rp");
    }

    # Scope must be provided and cannot come from request or request_uri
    unless ( $oidc_request->{'scope'} ) {
        return $self->_failAuthorize( $req, msg => "Scope is required" );
    }

    # Extract request_uri/request parameter
    if ( my $request_uri = $oidc_request->{'request_uri'} ) {
        if (
            $self->isUriAllowedForRP(
                $request_uri, $rp, "oidcRPMetaDataOptionsRequestUris", 1
            )
          )
        {
            my $request = $self->getRequestJWT($request_uri);

            if ($request) {
                $oidc_request->{'request'} = $request;
            }
            else {
                return $self->_failAuthorize( $req,
                    msg => "Error with Request URI resolution" );
            }
        }
        else {
            return $self->_failAuthorize( $req,
                msg => "Request URI $request_uri is not allowed for $rp" );
        }
    }

    my $authMethod;
    if ( $oidc_request->{'request'} ) {
        if ( my ( $request, $alg ) =
            $self->decodeJWT( $oidc_request->{'request'}, undef, $rp ) )
        {
            $self->logger->debug("JWT signature request verified");

            $authMethod =
              $alg =~ /^HS/i
              ? 'client_secret_jwt'
              : 'private_key_jwt';

            # Override OIDC parameters by request content
            foreach ( keys %$request ) {
                $self->logger->debug( "Override $_ OIDC param"
                      . " by value present in request parameter" );

                if ( $_ eq "client_id" or $_ eq "response_type" ) {
                    if ( $oidc_request->{$_} ne $request->{$_} ) {
                        return $self->_failAuthorize(
                            $req,
                            msg => (
                                    "$_ from request JWT ("
                                  . $oidc_request->{$_}
                                  . ") does not match $_ from request URI ("
                                  . $request->{$_} . ")"
                            )
                        );
                    }
                }
                $oidc_request->{$_} = $request->{$_};
                $self->p->setHiddenFormValue( $req, $_, $request->{$_}, '', 0 );
            }
        }
        else {
            return $self->_failAuthorize( $req,
                msg => "JWT signature request can not be verified" );
        }
    }

    # Check all required parameters
    unless ( $oidc_request->{'redirect_uri'} ) {
        return $self->_failAuthorize( $req, msg => "Redirect URI is required" );
    }
    if ( $flow eq "implicit" and not defined $oidc_request->{'nonce'} ) {
        return $self->_failAuthorize( $req,
            msg => "Nonce is required for implicit flow" );
    }

    # Check if this RP is authorized
    if ( my $rule = $self->rpRules->{$rp} ) {
        my $ruleVariables =
          { %{ $req->sessionInfo || {} }, _oidc_grant_type => $flow };
        unless ( $rule->( $req, $ruleVariables ) ) {
            return $self->_failAuthorize(
                $req,
                msg => (
                        'User '
                      . $req->sessionInfo->{ $self->conf->{whatToTrace} }
                      . " is not authorized to access $rp"
                ),
                res        => PE_UNAUTHORIZEDPARTNER,
                userLogger => 1,
            );
        }
    }

    # Check redirect_uri
    my $redirect_uri = $oidc_request->{'redirect_uri'};
    if (
        !$self->_validateRedirectUri(



( run in 2.170 seconds using v1.01-cache-2.11-cpan-364913b4093 )