パート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番目のhandleAuthRequest
はAuthController
コントローラーにのみ必要であることを明確にする必要が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); }
ここでは、 SecureHandlerFunc
とTrustedHandlerFunc
2つの機能インターフェイスが使用されます。 最初のものは、クライアントからのユーザーヘッダーをチェックし、それらからAuthUser
トークンを作成して、 TrustedHandlerFunc
インターフェイスの次のメソッドにTrustedHandlerFunc
ます。 ここでは、トークンは許可ユーザーであることが期待されています。
これらのインターフェイスの実装の詳細は、前述の記事で既に説明されているため、説明しません。 違いは、ヘッダーに含まれるデータを承認し、結果をクライアントに送信する責任の内訳にあるとしか言えません。
Spring Securityなしではない
Spring SecurityをCORSと連携させるために接続する必要があったことに注意してください。
必要なヘッダーを追加するために、StackOverflowを使用したコードが使用され、わずかに再設計されました。 CorsFilterAdapter
クラスとSecurityConfig
クラスにあります。
おわりに
この記事では、簡単な日曜大工認証を行う方法について説明しました。