Googleログインとスプリングのセキュリティ設定を有効にする
18443 ワード
このプレゼンテーションは、Spring BootとAWSが独自にWebサービスマニュアルに基づいて作成したものです.
1.ドメインユーザークラスの作成
ⓐ @Enumerated(EnumType.STRING) JPAを使用してデータベースを格納場合、Enum値を格納する理由を決定する .デフォルト記憶整数 の数字が格納されている場合、データベース内の値がどのコードを意味するかは判断できないため、宣言は文字列 として格納することができる.
ユーザ権限を管理するEnumクラス スプリングパリティでは、パーミッションコードに常にROLEがある必要があります.合計 2.スプリング安全性の設定
spring-boot-starter-oauth2-client ソーシャルログインなどのクライアントのソーシャル機能への依存性 デフォルト管理 spring-security-oauth 2-clientおよびspring-security-oauth 2-jose
セキュリティクラス ⓐ @EnableWebSecurity Spring Security設定を有効にする ⓑ csrf().disable().headers().frameOptions().disable() h 2-コンソール画面 を使用する処理オプションを無効にする
ⓒ authorizeRequests()
オプション URL固有の権限管理の開始点 を設定する.
antMatchersオプションを使用するには、 authorizeRequestsを宣言する必要があります.
ⓓ antMatchers("/api/v1/**") 権限管理オプション URL、HTTP方法で を管理できる permitAll()オプションを使用して、完全権限 を付与 hasRole()オプションで、 へのユーザーのアクセスを許可します.
ⓔ anyRequest() は、設定値以外のURL を示す.認証()を追加し、他のすべてのURLが認証ユーザによって を使用できるようにする.認証ユーザ、すなわちログインユーザ .
ⓕ logout().logoutSuccessUrl("/") ログアウト機能の複数の設定エントリポイント ログアウトに成功すると、"/"アドレス が返されます.
ⓖ oauth2Login() OAuth 2登録機能の冗長設定エントリポイント ⓗ userInfoEndpoint() OAuth 2ログイン成功後のユーザ情報入力設定 特定のユーザー・サービスユーザー・サービス・インタフェースのインプリメンテーションを登録し、ソーシャル・ログインが成功したときに後続の操作を実行する リソースサーバ(すなわち、ソーシャルサービス)は、ユーザ情報を取得する場合に実行すべき他の機能 を指定することができる.
は、ユーザーがGoogleからログインして取得した情報に基づいて、情報の購読や変更、セッションの保存などの機能をサポートします. ⓐ registrationId コード 現在ログイン中のサービスを区別する現在、上記のコードはGoogleのみを使用しているため不要な値であるが、他のログイン連動時に他のサービス(ex.NAVERログイン、Google、KACAのID値を検証するための)であるかどうかを区別するための である.
ⓑ userNameAttributeName OAuth 2登録に必要なフィールド値(プライマリキーと同じ) Google基本サポートコードですが、NAVERKACAなどはサポートされていません!Googleの基本コードは「sub」 以降は、NAVERログインとGoogleログインを同時にサポートする場合に を使用します.
ⓒ OAuthAttributes Auth 2 UserServiceクラス、インポートされたAuth 2 Userプロパティを含む 以降、Naverなどの他のソーシャルサイトもこのようなサイト を使用している.
ⓓ SessionUser セッションにおいてユーザ情報を格納DTOクラス
作成 DTOパッケージ作成クラス ⓐ of() Auth 2 Userが返すユーザ情報はMapであるため、各値 を変換する必要がある.
ⓑ toEntity()
作成 ユーザーエンティティ アイデンティティー属性からエンティティを作成する場合は、初回登録時の である.登録時のデフォルト権限をGUIとするために、キャラクタビルダー値はRoleとなります.GUEST値 を提供 AuthAttributesクラスの作成が完了した場合、同じパッケージにSessionUserクラス が作成されます.
セッションに格納するには、クラスのシリアル化が必要です. ユーザクラスはエンティティであるため、シリアル化が困難である エンティティークラスは、他のエンティティーとの関係がいつ確立されるか分からない exなどのサブエンティティ@OneToManyまたは@MantoManyを持っている場合、シリアル・ターゲットにもエンティティが含まれているため、パフォーマンスの問題や負の影響を及ぼす可能性があります.
3.テストログイン
ⓐ {{#userName}} マストリッチは是非だけを判断し、なければ は、常に最終値 を超える必要があります.
ⓑ a href="/logout"
標準 の登録抹消URL 、すなわち、開発者は、低URLのコントローラ を作成する必要がない. SecurityConfigクラス変更可能URL ⓒ {{^userName}} マストリッチ使用^この値が存在しない場合、使用^ ⓓ a href="/oauth2/authorization/google" Spring Securityデフォルトで提供されるGoogleログインURL ログインボタン画面
Googleログイン
チェック登録情報DB
投稿登録(GUEST状態)
権限を変更して登録
1.ドメインユーザークラスの作成
User
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Getter
@NoArgsConstructor
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String email;
@Column
private String picture;
@Enumerated(EnumType.STRING) ⓐ
@Column(nullable = false)
private Role role;
@Builder
public User(String name, String email, String picture, Role role) {
this.name = name;
this.email = email;
this.picture = picture;
this.role = role;
}
public User update(String name, String picture) {
this.name = name;
this.picture = picture;
return this;
}
public String getRoleKey() {
return this.role.getKey();
}
}
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Getter
@NoArgsConstructor
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String email;
@Column
private String picture;
@Enumerated(EnumType.STRING) ⓐ
@Column(nullable = false)
private Role role;
@Builder
public User(String name, String email, String picture, Role role) {
this.name = name;
this.email = email;
this.picture = picture;
this.role = role;
}
public User update(String name, String picture) {
this.name = name;
this.picture = picture;
return this;
}
public String getRoleKey() {
return this.role.getKey();
}
}
Role
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public enum Role {
GUEST("ROLE_GUEST", "손님"),
USER("ROLE_USER", "일반 사용자");
private final String key;
private final String title;
}
UserRepository
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email);
}
2.スプリング安全性の設定
2.1 build.grade依存性の追加
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
2.2 config.authパッケージの作成
2.2.1 SecurithConfig
import com.study.aws.studyspringbootaws.domain.user.Role;
import lombok.RequiredArgsConstructor;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@RequiredArgsConstructor
@EnableWebSecurity ⓐ
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final CustomOAuth2UserService customOAuth2UserService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.headers().frameOptions().disable() ⓑ
.and()
.authorizeRequests() ⓒ
.antMatchers("/", "/css/**", "/images/**", "/js/**", "/h2-console/**")
.permitAll()
.antMatchers("/api/v1/**") ⓓ
.hasRole(Role.USER.name())
.anyRequest() ⓔ
.authenticated()
.and()
.logout()
.logoutSuccessUrl("/") ⓕ
.and()
.oauth2Login() ⓖ
.userInfoEndpoint() ⓗ
.userService(customOAuth2UserService) ⓘ
;
}
}
オプション
antMatchersオプションを使用するには、
2.2.2 CustomOAuth2UserService
@RequiredArgsConstructor
@Service
public class CustomOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
private final UserRepository userRepository;
private final HttpSession httpSession;
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2UserService delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);
String registrationId = userRequest.getClientRegistration().getRegistrationId(); ⓐ
String userNameAttributeName =
userRequest.getClientRegistration()
.getProviderDetails()
.getUserInfoEndpoint()
.getUserNameAttributeName(); ⓑ
OAuthAttributes attributes = OAuthAttributes.of(registrationId,
userNameAttributeName,
oAuth2User.getAttributes()); ⓒ
User user = saveOrUpdate(attributes);
httpSession.setAttribute("user", new SessionUser(user)); ⓓ
return new DefaultOAuth2User(
Collections.singleton(new SimpleGrantedAuthority(user.getRoleKey())),
attributes.getAttributes(),
attributes.getNameAttributeKey()
);
}
private User saveOrUpdate(OAuthAttributes attributes) {
User user = userRepository.findByEmail(attributes.getEmail())
.map(entity -> entity.update(attributes.getName(),
attributes.getPicture()))
.orElse(attributes.toEntity());
return userRepository.save(user);
}
}
2.2.3 OAuthAttributes
作成
@Getter
public class OAuthAttributes {
private Map<String, Object> attributes;
private String nameAttributeKey;
private String name;
private String email;
private String picture;
@Builder
public OAuthAttributes(Map<String, Object> attributes,
String nameAttributeKey, String name,
String email, String picture) {
this.attributes = attributes;
this.nameAttributeKey = nameAttributeKey;
this.name = name;
this.email = email;
this.picture = picture;
}
public static OAuthAttributes of(String registrationId,
String userNameAttributeName,
Map<String, Object> attributes) { ⓐ
return ofGoogle(userNameAttributeName, attributes);
}
private static OAuthAttributes ofGoogle(String userNameAttributeName,
Map<String, Object> attributes) {
return OAuthAttributes.builder()
.name((String) attributes.get("name"))
.email((String) attributes.get("email"))
.picture((String) attributes.get("picture"))
.attributes(attributes)
.nameAttributeKey(userNameAttributeName)
.build()
;
}
public User toEntity() { ⓑ
return User.builder()
.name(name)
.email(email)
.picture(picture)
.role(Role.GUEST)
.build();
}
}
作成
2.2.4 SessionUser
@Getter
public class SessionUser implements Serializable {
private String name;
private String email;
private String picture;
public SessionUser(User user) {
this.name = user.getName();
this.email = user.getEmail();
this.picture = user.getPicture();
}
}
2.2.5なぜUserクラスを使用しないで単独でSessionUserを作成しますか?
3.テストログイン
3.1ログイン機能を画面に追加する
3.1.1 index.mustache
<h1>스프링 부트로 시작하는 웹 서비스</h1>
<div class="col-md-12">
<div class="row">
<div class="col-md-6">
<a href="/posts/save" role="button" class="btn btn-primary">글 등록</a>
{{#userName}} ⓐ
Logged in as : <span id="user">{{userName}}</span>
<a href="/logout" class="btn btn-info active" role="button">Logout</a> ⓑ
{{/userName}}
{{^userName}} ⓒ
<a href="/oauth2/authorization/google" class="btn btn-info active" role="button">Google Login</a> ⓓ
{{/userName}}
</div>
</div>
</div>
<h1>스프링 부트로 시작하는 웹 서비스</h1>
<div class="col-md-12">
<div class="row">
<div class="col-md-6">
<a href="/posts/save" role="button" class="btn btn-primary">글 등록</a>
{{#userName}} ⓐ
Logged in as : <span id="user">{{userName}}</span>
<a href="/logout" class="btn btn-info active" role="button">Logout</a> ⓑ
{{/userName}}
{{^userName}} ⓒ
<a href="/oauth2/authorization/google" class="btn btn-info active" role="button">Google Login</a> ⓓ
{{/userName}}
</div>
</div>
</div>
標準
3.1.2 indexController
private final HttpSession httpSession;
@GetMapping("/")
public String index(Model model) {
model.addAttribute("posts", postsService.findAllDesc());
SessionUser user = (SessionUser) httpSession.getAttribute("user");
if (user != null) {
model.addAttribute("userName", user.getName());
}
return "index";
}
3.2プロジェクトの実行とテスト
Reference
この問題について(Googleログインとスプリングのセキュリティ設定を有効にする), 我々は、より多くの情報をここで見つけました https://velog.io/@young_209/구글-로그인-연동-및-스프링-시큐리티-설정テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol