Spring SecurityなしのAngularおよびSpringでの認証(Spring上のサーバー)

パート2. Spring上のサーバー


この記事について


この記事では、このタスクの既成のソリューションを使用せずに簡単な認証を作成する方法を説明します。 AAA(認証、承認、アカウンティング)を書きたい初心者には便利です。 AngularのクライアントリポジトリSpringのサーバーリポジトリ


この記事では、Springのサーバー側コードの抜粋を作成します。


Spring認証サーバー


プロジェクト構造


. └── backendspring ├── BackendspringApplication.java # Spring  ├── config │ ├── AppProperties.java │ ├── AuthAuthority.java #       │ ├── CorsFilterAdapter.java #  CORS │ ├── ErrorMessages.java │ ├── IAuthority.java #     │ ├── RequestConstants.java │ ├── DefendedAuthority.java #      │ └── SecurityConfig.java #  CORS  Spring Security ├── controller │ ├── AuthController.java #   │ └── ProtectedPingPongController.java #   ├── dao │ ├── BaseDao.java │ └── SecureUserDao.java # DAO        ├── exception │ ├── AuthException.java │ └── PingPongException.java ├── function │ ├── BaseHandlerFunc.java #       ModelHandlerFunc.java │ ├── TrustedHandlerFunc.java #       │ └── SecureHandlerFunc.java #       ├── model │ ├── Answer.java #   -   │ ├── AuthUser.java #        │ ├── BaseDomain.java │ ├── EnumAuthority.java # Enum      │ ├── MessagePayload.java │ ├── MessageResponse.java │ ├── Payload.java #      /  JSON │ ├── PingPayload.java # ,     │ ├── PongPayload.java # ,    │ ├── UserCredentials.java #   /  │ └── SecureUser.java #       └── service ├── PingPongService.java # ,         ├── SecureUserService.java # ***,     /*** └── SecureUtils.java #      

認証/承認/登録サービス(SecureUserService)


SecureUserServiceこの記事SecureUserService主なサービスは、意図されたものです。


次のメソッドを実装します。


public Optional<AuthUser> register(UserCredentials usercredentials) -ユーザー登録。


public Optional<AuthUser> authorize(UserCredentials usercredentials) -承認またはユーザーログイン。


public Optional<AuthUser> authenticate(AuthUser authUser) -ユーザー権限の認証または検証。


public Optional<AuthUser> logout(AuthUser authUser) -ユーザーが現在サイトにいる情報を終了または削除します。


ユーザー認証コードを提供します:


 //      String credentials = usercredentials.getCredentials(); String salt = secureUser.getSalt(); String clientDigest = SecureUtils.digest(credentials + salt); //         if (clientDigest.equals(secureUser.getDigest())) { //   AccessToken      SecureUser TokenPair accessToken = getAccessToken(secureUser); //    String userSession = getUserSession(); //  AccessToken   secureUser.setSecureToken(accessToken.secureToken); secureUser.setAccessToken(accessToken.accessToken); secureUser.setUserSession(userSession); secureUserDao.save(secureUser); //  AccessToken,       String userId = secureUser.getId(); Set<EnumAuthority> authorities = secureUser.getAuthorities(); AuthUser authUser = AuthUser.simpleUser(userId, username, accessToken.accessToken, userSession, authorities); return authUser; } 

一般的に、標準アルゴリズム。


はい、AccessTokenを取得するためにユーザーデータを使用しません。 ランダムな文字列を生成し、標準のjavax.crypto暗号化アルゴリズムで暗号化します。


クライアント認証コントローラー(AuthController)


クライアントへの応答を生成するために、 この記事で前述した方法を使用しました


この例では、いくつかの単純化を行いました。 ただし、ここでは、Java SE 8の機能インターフェイスが引き続き使用されます。


サイトでクライアントを承認した後、クライアントのリクエストにどのように対応するかの例を示します。


 @PostMapping("authorize") public @ResponseBody Answer authorize(@RequestBody UserCredentials usercredentials, HttpServletResponse response) { //       return ((TrustedHandlerFunc<UserCredentials>) (data) -> secureUserService.authorize(data) .map(Answer::ok) .orElseGet(Answer::forbidden)) .handleAuthRequest(response, usercredentials); } 

承認されていない要求を処理するには、 TrustedHandlerFunc機能インターフェイスを使用します。 Answer process(T data)メソッドが含まれています。 このメソッドはコントローラーに実装され、 SecureUserService::authorizeメソッドを呼び出します。 このサービスの応答は、承認が成功した場合はAnswer::okメソッド、承認が失敗した場合はAnswer::forbiddenメソッドと結び付けられます。 また、インターフェイスには、デフォルトのメソッドTrustedHandlerFunc::handleRequestおよびTrustedHandlerFunc::handleAuthRequest 、これらはAnswer process(T data)メソッドのAnswer process(T data)を選択します。 UserCredentialsは次のUserCredentialsです。 最初のhandleRequestメソッドは検証済みのAuthUserトークンの存在を前提とし、2番目のhandleAuthRequestAuthControllerコントローラーにのみ必要であることを明確にする必要がAuthUserます。


クライアント要求処理コントローラー(ProtectedPingPongController)


ユーザーリクエストハンドラーについて考えます。 PingPongServiceと呼びましょう。 慣例により、このコントローラーは許可されていないクライアントが使用できないようにする必要があります。


pingリクエストに対する応答を作成する例を次に示しping


 @PostMapping("ping") public @ResponseBody Answer ping(@RequestBody PingPayload ping, HttpServletRequest request, HttpServletResponse response) { return authenticateRequestService .getAuthenticatedUser(request, DefendedAuthority.PING) .map(authUser -> //    ((TrustedHandlerFunc<PingPayload>) (data) -> pingPongService.getPong(data, authUser) //      .map(Answer::ok) .orElseGet(Answer::forbidden) ).handleRequest(response, ping, authUser) //   ).orElseThrow(AuthException::forbidden); } 

ここでは、 SecureHandlerFuncTrustedHandlerFunc 2つの機能インターフェイスが使用されます。 最初のものは、クライアントからのユーザーヘッダーをチェックし、それらからAuthUserトークンを作成して、 TrustedHandlerFuncインターフェイスの次のメソッドにTrustedHandlerFuncます。 ここでは、トークンは許可ユーザーであることが期待されています。


これらのインターフェイスの実装の詳細は、前述の記事で既に説明されているため、説明しません。 違いは、ヘッダーに含まれるデータを承認し、結果をクライアントに送信する責任の内訳にあるとしか言えません。


Spring Securityなしではない


Spring SecurityをCORSと連携させるために接続する必要があったことに注意してください。


必要なヘッダーを追加するために、StackOverflowを使用したコードが使用され、わずかに再設計されました。 CorsFilterAdapterクラスとSecurityConfigクラスにあります。


おわりに


この記事では、簡単な日曜大工認証を行う方法について説明しました。


参照資料




Source: https://habr.com/ru/post/J354862/


All Articles