Search in sources :

Example 1 with Scope

use of com.apifest.oauth20.bean.Scope in project xian by happyyangyuan.

the class Authenticator method issueAccessToken.

/**
 * 支持json和form两种表单形式
 */
public AccessToken issueAccessToken(FullHttpRequest req) throws OAuthException {
    TokenRequest tokenRequest = TokenRequest.create(req);
    tokenRequest.validate();
    // check valid client_id, client_secret and status of the client app should be active
    if (!isActiveClient(tokenRequest.getClientId(), tokenRequest.getClientSecret())) {
        throw new OAuthException(ResponseBuilder.INVALID_CLIENT_CREDENTIALS, HttpResponseStatus.BAD_REQUEST);
    }
    AccessToken accessToken = null;
    if (TokenRequest.AUTHORIZATION_CODE.equals(tokenRequest.getGrantType())) {
        AuthCode authCode = findAuthCode(tokenRequest);
        // TODO: REVISIT: Move client_id check to db query
        if (authCode != null) {
            if (!tokenRequest.getClientId().equals(authCode.getClientId())) {
                throw new OAuthException(ResponseBuilder.INVALID_CLIENT_ID, HttpResponseStatus.BAD_REQUEST);
            }
            if (authCode.getRedirectUri() != null && !tokenRequest.getRedirectUri().equals(authCode.getRedirectUri())) {
                throw new OAuthException(ResponseBuilder.INVALID_REDIRECT_URI, HttpResponseStatus.BAD_REQUEST);
            } else {
                // invalidate the auth code
                db.updateAuthCodeValidStatus(authCode.getCode(), false);
                accessToken = new AccessToken(TOKEN_TYPE_BEARER, getExpiresIn(TokenRequest.PASSWORD, authCode.getScope()), authCode.getScope(), getExpiresIn(TokenRequest.REFRESH_TOKEN, authCode.getScope()));
                accessToken.setUserId(authCode.getUserId());
                accessToken.setClientId(authCode.getClientId());
                accessToken.setCodeId(authCode.getId());
                db.storeAccessToken(accessToken);
            }
        } else {
            throw new OAuthException(ResponseBuilder.INVALID_AUTH_CODE, HttpResponseStatus.BAD_REQUEST);
        }
    } else if (TokenRequest.REFRESH_TOKEN.equals(tokenRequest.getGrantType())) {
        accessToken = db.findAccessTokenByRefreshToken(tokenRequest.getRefreshToken(), tokenRequest.getClientId());
        if (accessToken != null) {
            if (!accessToken.refreshTokenExpired()) {
                String validScope;
                if (tokenRequest.getScope() != null) {
                    if (scopeService.scopeAllowed(tokenRequest.getScope(), accessToken.getScope())) {
                        validScope = tokenRequest.getScope();
                    } else {
                        throw new OAuthException(ResponseBuilder.SCOPE_NOK_MESSAGE, HttpResponseStatus.BAD_REQUEST);
                    }
                } else {
                    validScope = accessToken.getScope();
                }
                db.updateAccessTokenValidStatus(accessToken.getToken(), false);
                AccessToken newAccessToken = new AccessToken(TOKEN_TYPE_BEARER, getExpiresIn(TokenRequest.PASSWORD, validScope), validScope, accessToken.getRefreshToken(), accessToken.getRefreshExpiresIn());
                newAccessToken.setUserId(accessToken.getUserId());
                newAccessToken.setDetails(accessToken.getDetails());
                newAccessToken.setClientId(accessToken.getClientId());
                db.storeAccessToken(newAccessToken);
                db.removeAccessToken(accessToken.getToken());
                return newAccessToken;
            } else {
                db.removeAccessToken(accessToken.getToken());
                throw new OAuthException(ResponseBuilder.INVALID_REFRESH_TOKEN, HttpResponseStatus.BAD_REQUEST);
            }
        } else {
            throw new OAuthException(ResponseBuilder.INVALID_REFRESH_TOKEN, HttpResponseStatus.BAD_REQUEST);
        }
    } else if (TokenRequest.CLIENT_CREDENTIALS.equals(tokenRequest.getGrantType())) {
        ClientCredentials clientCredentials = db.findClientCredentials(tokenRequest.getClientId());
        String scope = scopeService.getValidScopeByScope(tokenRequest.getScope(), clientCredentials.getScope());
        if (scope == null) {
            throw new OAuthException(ResponseBuilder.SCOPE_NOK_MESSAGE, HttpResponseStatus.BAD_REQUEST);
        }
        accessToken = new AccessToken(TOKEN_TYPE_BEARER, getExpiresIn(TokenRequest.CLIENT_CREDENTIALS, scope), scope, false, null);
        accessToken.setClientId(tokenRequest.getClientId());
        Map<String, String> applicationDetails = clientCredentials.getApplicationDetails();
        if ((applicationDetails != null) && (applicationDetails.size() > 0)) {
            // For backward compatibility
            accessToken.setDetails(applicationDetails);
            accessToken.setApplicationDetails(applicationDetails);
        }
        db.storeAccessToken(accessToken);
    } else if (TokenRequest.PASSWORD.equals(tokenRequest.getGrantType())) {
        ClientCredentials clientCredentials = db.findClientCredentials(tokenRequest.getClientId());
        String scope = scopeService.getValidScopeByScope(tokenRequest.getScope(), clientCredentials.getScope());
        if (scope == null) {
            throw new OAuthException(ResponseBuilder.SCOPE_NOK_MESSAGE, HttpResponseStatus.BAD_REQUEST);
        }
        try {
            UserDetails userDetails = authenticateUser(tokenRequest.getUsername(), tokenRequest.getPassword(), req);
            if (userDetails != null && userDetails.getUserId() != null) {
                accessToken = new AccessToken(TOKEN_TYPE_BEARER, getExpiresIn(TokenRequest.PASSWORD, scope), scope, getExpiresIn(TokenRequest.REFRESH_TOKEN, scope));
                accessToken.setUserId(userDetails.getUserId());
                accessToken.setDetails(userDetails.getDetails());
                accessToken.setClientId(tokenRequest.getClientId());
                accessToken.setApplicationDetails(clientCredentials.getApplicationDetails());
                db.storeAccessToken(accessToken);
            } else {
                throw new OAuthException(ResponseBuilder.INVALID_USERNAME_PASSWORD, HttpResponseStatus.UNAUTHORIZED);
            }
        } catch (AuthenticationException e) {
            // for instance, if the user authentication requires more user details as a subsequent step
            if (e.getResponse() != null) {
                String responseContent = ((FullHttpResponse) (e.getResponse())).content().toString(CharsetUtil.UTF_8);
                throw new OAuthException(e, responseContent, e.getResponse().getStatus());
            } else {
                LOG.error("Cannot authenticate user", e);
                // NOSONAR
                throw new OAuthException(e, ResponseBuilder.CANNOT_AUTHENTICATE_USER, HttpResponseStatus.UNAUTHORIZED);
            }
        }
    } else if (tokenRequest.getGrantType().equals(OAuthConfig.getCustomGrantType())) {
        String scope = scopeService.getValidScope(tokenRequest.getScope(), tokenRequest.getClientId());
        if (scope == null) {
            throw new OAuthException(ResponseBuilder.SCOPE_NOK_MESSAGE, HttpResponseStatus.BAD_REQUEST);
        }
        try {
            accessToken = new AccessToken(TOKEN_TYPE_BEARER, getExpiresIn(TokenRequest.PASSWORD, scope), scope, getExpiresIn(TokenRequest.REFRESH_TOKEN, scope));
            accessToken.setClientId(tokenRequest.getClientId());
            UserDetails userDetails = callCustomGrantTypeHandler(req);
            if (userDetails != null && userDetails.getUserId() != null) {
                accessToken.setUserId(userDetails.getUserId());
                accessToken.setDetails(userDetails.getDetails());
            }
            db.storeAccessToken(accessToken);
        } catch (AuthenticationException e) {
            LOG.error("Cannot authenticate user", e);
            throw new OAuthException(e, ResponseBuilder.CANNOT_AUTHENTICATE_USER, HttpResponseStatus.UNAUTHORIZED);
        }
    }
    return accessToken;
}
Also used : UserDetails(com.apifest.oauth20.api.UserDetails) AuthenticationException(com.apifest.oauth20.api.AuthenticationException) AccessToken(info.xiancloud.core.support.authen.AccessToken) TokenRequest(com.apifest.oauth20.bean.token_request.TokenRequest)

Example 2 with Scope

use of com.apifest.oauth20.bean.Scope in project xian by happyyangyuan.

the class OAuth20Handler method handlePostAccessToken.

@DocOAuth20Sub(name = "handlePostAccessToken", dec = "获取新access_token", method = "POST", url = "/oauth2.0/tokens", args = { @DocOAuth20SubIn(name = "grant_type", dec = "grant_type有四种类型,分别为authorization_code,refresh_token,client_credentials,password", require = true, type = String.class), @DocOAuth20SubIn(name = "client_id", dec = "client_id", require = true, type = String.class), @DocOAuth20SubIn(name = "client_secret", dec = "client_secret", require = true, type = String.class), @DocOAuth20SubIn(name = "redirect_uri", dec = "仅当grant_type为authorization_code时必填", require = false, type = String.class), @DocOAuth20SubIn(name = "code", dec = "仅当grant_type为authorization_code时必填", require = false, type = String.class), @DocOAuth20SubIn(name = "refresh_token", dec = "仅当grant_type为refresh_token时必填", require = false, type = String.class), @DocOAuth20SubIn(name = "scope", dec = "仅当grant_type为refresh_token,client_credentials时填写有效", require = false, type = String.class), @DocOAuth20SubIn(name = "username", dec = "仅当grant_type为password时必填", require = false, type = String.class), @DocOAuth20SubIn(name = "password", dec = "仅当grant_type为password时必填", require = false, type = String.class) })
FullHttpResponse handlePostAccessToken(FullHttpRequest request) {
    FullHttpResponse response = null;
    String contentType = request.headers().get(HttpHeaderNames.CONTENT_TYPE);
    if (contentType != null && (contentType.contains(HttpHeaderValues.APPLICATION_X_WWW_FORM_URLENCODED) || contentType.contains(HttpHeaderValues.APPLICATION_JSON))) {
        try {
            AccessToken accessToken = auth.issueAccessToken(request);
            if (accessToken != null) {
                String jsonString = JSON.toJSONString(accessToken);
                LOG.debug("access token:" + jsonString);
                response = ResponseBuilder.createOkResponse(jsonString);
            /*accessTokensLog.debug(String.format("token {%s}", jsonString));*/
            }
        } catch (OAuthException ex) {
            response = ResponseBuilder.createOAuthExceptionResponse(ex);
            invokeExceptionHandler(ex, request);
        }
        if (response == null) {
            response = ResponseBuilder.createBadRequestResponse(ResponseBuilder.CANNOT_ISSUE_TOKEN);
        }
    } else {
        response = ResponseBuilder.createResponse(HttpResponseStatus.BAD_REQUEST, ResponseBuilder.UNSUPPORTED_MEDIA_TYPE);
    }
    return response;
}
Also used : AccessToken(info.xiancloud.core.support.authen.AccessToken) OAuthException(com.apifest.oauth20.bean.OAuthException) DocOAuth20Sub(info.xiancloud.core.apidoc.annotation.DocOAuth20Sub)

Example 3 with Scope

use of com.apifest.oauth20.bean.Scope in project xian by happyyangyuan.

the class OAuth20Handler method handleUpdateClientApplication.

@DocOAuth20Sub(name = "handleUpdateClientApplication", dec = "更新单个application", method = "PUT", url = "/oauth2.0/applications/{LOCAL_NODE_ID}", args = { @DocOAuth20SubIn(name = "description", dec = "用户自定义描述", require = true, type = String.class), @DocOAuth20SubIn(name = "scope", dec = "支持由空格分割的多个scope", require = true, type = String.class), @DocOAuth20SubIn(name = "status", dec = "值为1或者0,1为有效,0为无效", require = true, type = Integer.class), @DocOAuth20SubIn(name = "client_id", dec = "client_id", require = true, type = String.class), @DocOAuth20SubIn(name = "application_details", dec = "用户自定义的多个键值对", require = false, type = Map.class) })
FullHttpResponse handleUpdateClientApplication(FullHttpRequest req) {
    FullHttpResponse response = null;
    Matcher m = APPLICATION_PATTERN.matcher(req.uri());
    if (m.find()) {
        String clientId = m.group(1);
        try {
            if (auth.updateClientApp(req, clientId)) {
                response = ResponseBuilder.createOkResponse(ResponseBuilder.CLIENT_APP_UPDATED);
            }
        } catch (OAuthException ex) {
            response = ResponseBuilder.createOAuthExceptionResponse(ex);
            invokeExceptionHandler(ex, req);
        }
    } else {
        response = ResponseBuilder.createNotFoundResponse();
    }
    return response;
}
Also used : Matcher(java.util.regex.Matcher) OAuthException(com.apifest.oauth20.bean.OAuthException) DocOAuth20Sub(info.xiancloud.core.apidoc.annotation.DocOAuth20Sub)

Example 4 with Scope

use of com.apifest.oauth20.bean.Scope in project xian by happyyangyuan.

the class OAuth20Handler method handleUpdateScope.

@DocOAuth20Sub(name = "handleUpdateScope", dec = "更新已存在的scope", method = "PUT", url = "/oauth2.0/scopes/{scopeName}", args = { @DocOAuth20SubIn(name = "scope", dec = "一次仅能更新一个scope", require = true, type = String.class), @DocOAuth20SubIn(name = "description", dec = "自定义scope描述", require = true, type = String.class), @DocOAuth20SubIn(name = "cc_expires_in", dec = "grant_type为client_credentials时access_token过期时间", require = true, type = Integer.class), @DocOAuth20SubIn(name = "pass_expires_in", dec = "grant_type为password时access_token过期时间", require = true, type = Integer.class), @DocOAuth20SubIn(name = "refreshExpiresIn", dec = "grant_type为refresh_token时access_token过期时间", require = true, type = Integer.class) })
FullHttpResponse handleUpdateScope(FullHttpRequest req) {
    FullHttpResponse response;
    Matcher m = OAUTH_CLIENT_SCOPE_PATTERN.matcher(req.uri());
    if (m.find()) {
        String scopeName = m.group(1);
        ScopeService scopeService = getScopeService();
        try {
            String responseMsg = scopeService.updateScope(req, scopeName);
            response = ResponseBuilder.createOkResponse(responseMsg);
        } catch (OAuthException e) {
            invokeExceptionHandler(e, req);
            response = ResponseBuilder.createResponse(e.getHttpStatus(), e.getMessage());
        }
    } else {
        response = ResponseBuilder.createNotFoundResponse();
    }
    return response;
}
Also used : Matcher(java.util.regex.Matcher) OAuthException(com.apifest.oauth20.bean.OAuthException) DocOAuth20Sub(info.xiancloud.core.apidoc.annotation.DocOAuth20Sub)

Example 5 with Scope

use of com.apifest.oauth20.bean.Scope in project xian by happyyangyuan.

the class ScopeService method getScopes.

protected String getScopes(String clientId) throws OAuthException {
    ClientCredentials credentials = DBManagerFactory.getInstance().findClientCredentials(clientId);
    String jsonString;
    if (credentials != null) {
        // scopes are separated by comma
        String scopes = credentials.getScope();
        String[] s = scopes.split(SPACE);
        List<Scope> result = new ArrayList<Scope>();
        for (String name : s) {
            Scope scope = DBManagerFactory.getInstance().findScope(name);
            result.add(scope);
        }
        try {
            jsonString = JSON.toJSONString(result);
        } catch (Exception e) {
            LOG.error("cannot load scopes per LOCAL_NODE_ID", e);
            throw new OAuthException(e, null, HttpResponseStatus.BAD_REQUEST);
        }
    } else {
        throw new OAuthException(null, HttpResponseStatus.NOT_FOUND);
    }
    return jsonString;
}
Also used : Scope(com.apifest.oauth20.bean.Scope) OAuthException(com.apifest.oauth20.bean.OAuthException) ArrayList(java.util.ArrayList) ClientCredentials(com.apifest.oauth20.bean.ClientCredentials) OAuthException(com.apifest.oauth20.bean.OAuthException) IOException(java.io.IOException)

Aggregations

OAuthException (com.apifest.oauth20.bean.OAuthException)14 Scope (com.apifest.oauth20.bean.Scope)8 DocOAuth20Sub (info.xiancloud.core.apidoc.annotation.DocOAuth20Sub)7 IOException (java.io.IOException)5 Matcher (java.util.regex.Matcher)4 AccessToken (info.xiancloud.core.support.authen.AccessToken)3 ArrayList (java.util.ArrayList)3 JSONObject (com.alibaba.fastjson.JSONObject)2 ClientCredentials (com.apifest.oauth20.bean.ClientCredentials)2 AuthenticationException (com.apifest.oauth20.api.AuthenticationException)1 UserDetails (com.apifest.oauth20.api.UserDetails)1 ApplicationInfo (com.apifest.oauth20.bean.ApplicationInfo)1 TokenRequest (com.apifest.oauth20.bean.token_request.TokenRequest)1 DBManager (com.apifest.oauth20.persistence.DBManager)1 ByteBuf (io.netty.buffer.ByteBuf)1 DefaultFullHttpRequest (io.netty.handler.codec.http.DefaultFullHttpRequest)1 FullHttpRequest (io.netty.handler.codec.http.FullHttpRequest)1 URISyntaxException (java.net.URISyntaxException)1 List (java.util.List)1