使用Okta和JWT保护laravel api服务

使用Okta和JWT保护laravel api服务,laravel,jwt,okta,Laravel,Jwt,Okta,试图使用OKTA和JWT组合一个解决方案来保护Laravel5.4API。我有一个SPA,它通过OKTA登录到我的应用程序,并检索访问令牌和id令牌。它还使用'Authorization':Bearer${accessToken}将此消息传递给报头中的API调用,但现在我正在努力找到一个解决方案,在Laravel后端中使用OKTA验证此访问令牌。一直在关注tymon/jwt auth,但无法解决如何添加自定义解决方案来验证令牌,但我假设可以使用okta/jwt验证程序进行验证有人有任何样本/指南

试图使用OKTA和JWT组合一个解决方案来保护Laravel5.4API。我有一个SPA,它通过OKTA登录到我的应用程序,并检索访问令牌和id令牌。它还使用'Authorization':Bearer${accessToken}将此消息传递给报头中的API调用,但现在我正在努力找到一个解决方案,在Laravel后端中使用OKTA验证此访问令牌。一直在关注tymon/jwt auth,但无法解决如何添加自定义解决方案来验证令牌,但我假设可以使用okta/jwt验证程序进行验证有人有任何样本/指南吗?我们还研究了laravel/socialite和socialiteproviders/okta,但这似乎更多地是关于传统的后端登录,而不是SPA

我们的
okta/jwt验证程序
库应该能够在这里帮助您。您必须创建一个自定义中间件解决方案来捕获和授权基于承载令牌的请求。一旦在验证器库内部设置了该中间件,就可以运行以下操作来验证accessToken

$jwtVerifier = (new \Okta\JwtVerifier\JwtVerifierBuilder())
    ->setAudience('api://default')
    ->setClientId('{clientId}')
    ->setIssuer('https://{yourOktaDomain}.com/oauth2/default')
    ->build();

$jwt = $jwtVerifier->verify($jwt);
通过更改上面的客户端id和okta域,您应该能够将accessToken传递给verify方法。如果没有任何异常,可以假定jwt有效并批准请求


请参阅,以了解在验证JWT的有效性后,您可以访问哪些内容的信息。在SPA中,确保您还定义了发卡机构,这应该是一个有用的开始

//react login

this.oktaAuth = new OktaAuth({ 
  url: props.config.oktaUrl
  ,clientId:props.config.clientId
  ,redirectUri:props.config.redirectUri
  ,issuer: props.config.issuer
});
this.oktaAuth.signIn({
    username: this.state.username,
    password: this.state.password
})
.then((response) => {
    if (response.status === 'SUCCESS') {
        this.setState({
            sessionToken: response.sessionToken
        });
        this.oktaAuth.token.getWithoutPrompt({
            responseType: ['id_token', 'token']
            ,scopes: ['openid', 'email', 'profile']
            ,sessionToken: response.sessionToken
        })
        .then((tokenOrTokens) => {
            this.setState({
                tokenOrTokens: tokenOrTokens
            });
            window.localStorage.setItem('access_token', tokenOrTokens[1].accessToken);
        })
        .catch(function(err) {
            console.log('err', err);
        });
    }
})

//api call

const accessToken = window.localStorage.getItem('access_token') || null;

const config = {
  method: 'GET',
  headers: { 
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': `Bearer ${accessToken}` 
  },
};

fetch(url, config)
    .then((response) => {
    ... 

//laravel api route

Route::group(['prefix' => 'restricted', 'middleware' => ['okta.validate']], function() {
    Route::get('/getprotecteddata', 'MyController@getProtectedData');
});

//laravel kernel.php
protected $routeMiddleware = [
    ...
    'okta.validate' => \App\Http\Middleware\ValidateOKTAToken::class,
];


//laravel middleware

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;


class ValidateOKTAToken
{
    public function handle($request, Closure $next)
    {
        $token = $this->parseAuthHeader($request);
        $jwt = $this->validate($token);
        \Log::info("ValidateOKTAToken jwt=" . json_encode($jwt->toJson()));
        return $next($request);
    }


    protected function validate($token) {

        $oktaClientId = env('OKTA_CLIENTID');
        $oktaIssuer = env('OKTA_ISSUER');
        $oktaAudience = env('OKTA_AUDIENCE');

        $jwtVerifier = (new \Okta\JwtVerifier\JwtVerifierBuilder())
        ->setAudience($oktaAudience)
        ->setClientId($oktaClientId)
        ->setIssuer($oktaIssuer)
        ->build();

        $jwt = $jwtVerifier->verify($token);
        return $jwt;        
    }

    protected function parseAuthHeader(Request $request, $header = 'authorization', $method = 'bearer')
    {
        $header = $request->headers->get($header);

        if (! starts_with(strtolower($header), $method)) {
            return false;
        }

        return trim(str_ireplace($method, '', $header));
    }
}

谢谢,但是完全按照你的建议做,但是得到了InvalidArgumentException:无法验证JWS。在vendor/spomky labs/jose/src/Verifier.php中:146从oktaAuth.signIn传递accessToken检查了clientId、颁发者等以及所有有效的[{“idToken”:“…”、“expiresAt”:“,“scopes”:[“openid”,“email”],“authorizeUrl”:“https:\/\/dev XXX.oktapreview.com\/oauth2\/v1\/authorize”,“颁发者”:“https:\/\/dev XXX.oktapreview.com”,“clientId:“…”,“{”accessToken:“…”,“expiresAt:“…,”tokenType:“Bearer”,“scopes:”[“openid”,“email”],“authorizeUrl:“https:\/\/dev XXX.oktapreview.com\/oauth2\/v1\/authorize”,“userinfoUrl:”https:\/\/dev XXX.oktapreview.com\/oauth2\/v1\/userinfo“}]您应该传入JWT的字符串版本,而不是您提供的解码版本。