首页 文章

使用Okta和JWT保护laravel api服务

提问于
浏览
0

尝试使用OKTA和JWT整合解决方案来保护Laravel 5.4 api . 我有一个通过OKTA登录我的应用程序的SPA,并检索access_token和id_token . 它还使用'Authorization': Bearer ${accessToken} 将其传递给标头中的API调用,但现在我正在努力寻找一种解决方案,以便在Laravel后端内使用OKTA验证此访问令牌 . 一直在看tymon / jwt-auth但是无法锻炼如何添加自定义解决方案来验证令牌,但我认为可以使用okta / jwt-verifier完成任何人都有任何样本/指南吗?还看了laravel / socialite和socialiteproviders / okta,但这似乎更像是传统的后端登录而不是SPA

2 回答

  • 0

    我们的 okta/jwt-verifier 图书馆应该可以帮到你了 . 您必须创建自定义中间件解决方案,以根据承载令牌捕获和授权请求 . 在验证程序库内部设置中间件后,可以运行以下命令来验证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有效性后您有权访问的内容的信息,请参阅github repo readme

  • 0

    对于那些发现这篇文章 . 在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));
        }
    }
    

相关问题