質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
OAuth 2.0

OAuth 2.0(Open Authorization 2.0)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

1回答

6644閲覧

Spring BootでOAuth2を使うときのセッション保持方法

Youichi256

総合スコア204

OAuth 2.0

OAuth 2.0(Open Authorization 2.0)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

1グッド

1クリップ

投稿2017/06/05 11:38

###実現したいこと
Spring BootでOAuth2を使って認証しようとしています。
Googleでの認証は出来たのですが、そのあとのユーザ識別やログイン状態の保持方法が分かりません。

###困っていること、分からないこと

  • ログイン状態の保持期間を1時間とかにしたい

(GoogleのOAuth2の情報は30分でクリアされるようなので)

  • ユーザを一意に特定するのはOAuth2Authentication.getUserAuthentication().getDetails().get("sub")でよいか

(RootController.java 参照)

  • ログイン直後にユーザに関する情報をセッションに入れるタイミングがほしい

(onLogin()をオーバーライドするイメージ)

  • Google以外でもOAuthで認証するときに困らないような書き方

###関連ソース

  • RootController.java

Java

1@Controller 2@Slf4j 3public class RootController { 4 @RequestMapping("/") 5 public String index(Model model, HttpServletRequest request, OAuth2Authentication auth) { 6 if (request.isUserInRole("ROLE_USER")) { 7 model.addAttribute("user", request.getRemoteUser()); 8 Object authDetails = auth.getUserAuthentication().getDetails(); 9 Map<?, ?> mm = null; 10 if (authDetails instanceof LinkedHashMap) { 11 mm = (LinkedHashMap<?, ?>) authDetails; 12 } 13 model.addAttribute("sub", mm.get("sub")); 14 model.addAttribute("email", mm.get("email")); 15 16 log.info("logined:{}", mm.get("email")); 17 for (Entry<?, ?> m : mm.entrySet()) { 18 log.info("AUTH:{}={}", m.getKey(), m.getValue()); 19 } 20 } else { 21 log.info("no login"); 22 } 23 24 if (auth == null) { 25 log.info("auth:null"); 26 } else { 27 log.info("name:{}", auth); 28 } 29 30 return "index"; 31 } 32}
  • SecurityConfig.java

Java

1@Component 2@EnableOAuth2Sso 3public class SecurityConfig extends WebSecurityConfigurerAdapter { 4 @Override 5 public void configure(HttpSecurity http) throws Exception { 6 http 7 .authorizeRequests().antMatchers("/").permitAll().anyRequest().authenticated() 8 .and().logout().logoutSuccessUrl("/").permitAll(); 9 } 10}
  • application.yml

YAML

1security: 2 oauth2: 3 client: 4 clientId: xxx.apps.googleusercontent.com 5 clientSecret: yyy 6 accessTokenUri: https://www.googleapis.com/oauth2/v4/token 7 userAuthorizationUri: https://accounts.google.com/o/oauth2/v2/auth 8 clientAuthenticationScheme: form 9 scope: 10 openid 11 email 12 resource: 13 userInfoUri: https://www.googleapis.com/oauth2/v3/userinfo 14 preferTokenInfo: true 15
  • build.gradle

Gradle

1buildscript { 2 ext { 3 springBootVersion = '1.5.3.RELEASE' 4 } 5 repositories { 6 mavenCentral() 7 } 8 dependencies { 9 classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 10 } 11} 12 13apply plugin: 'java' 14apply plugin: 'eclipse-wtp' 15apply plugin: 'org.springframework.boot' 16apply plugin: 'war' 17 18war { 19 baseName = 'xxx' 20 version = '0.0.1' 21} 22 23sourceCompatibility = 1.8 24 25repositories { 26 mavenCentral() 27} 28 29configurations { 30 providedRuntime 31} 32 33dependencies { 34 compile('org.springframework.boot:spring-boot-configuration-processor') 35 compile('org.springframework.boot:spring-boot-starter-aop') 36 compile('org.springframework.boot:spring-boot-starter-data-jpa') 37 compile('org.springframework.boot:spring-boot-starter-security') 38 compile('org.springframework.boot:spring-boot-starter-thymeleaf') 39 compile('org.springframework.boot:spring-boot-starter-web') 40 compile('org.springframework.security.oauth:spring-security-oauth2') 41 compileOnly('org.projectlombok:lombok') 42 runtime('org.springframework.boot:spring-boot-devtools') //コード更新時にアプリケーションをリロード 43 runtime('org.postgresql:postgresql') 44 providedRuntime('org.springframework.boot:spring-boot-starter-tomcat') 45 testCompile('org.springframework.boot:spring-boot-starter-test') 46} 47 48bootRun { 49 jvmArgs = ['-Dspring.output.ansi.enabled=always'] //コンソールに色を付ける 50}

###補足情報
開発環境:Eclipse 4.6 (Pleiades)

A-pZ👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

複数の質問がありますので回答のみのものもあります。ご容赦ください。

  1. ログイン状態の保持期間を1時間とかにしたい

トークンの有効期限は変えられませんが、自動リフレッシュする機能と強制破棄する仕組みも提供されています。これで代替できるか検討してください。
https://developers.google.com/identity/protocols/OAuth2WebServer#offline

  1. ユーザを一意に特定するのはOAuth2Authentication.getUserAuthentication().getDetails().get("sub")でよいか

ユーザの定義が曖昧なので正解になるかはわかりませんが、Googleアカウント利用者を一意に定義できる値は sub で間違いはありません。Googleアカウント利用者ひとりにつき複数のメールアドレスが使えますが、この場合のsubの値は一意に紐づけられます。https://developers.google.com/identity/protocols/OpenIDConnect#server-flow

  1. ログイン直後にユーザに関する情報をセッションに入れるタイミングがほしい

ドンピシャのサンプルコードが以下にありますので参考にしてください。AuthenticationSuccessHandlerを実装するだけです。
https://javapointers.com/tutorial/spring-custom-authenticationsuccesshandler-example-2/

  1. Google以外でもOAuthで認証するときに困らないような書き方

具体的に書かれているControllerのコードは、Googleアカウントに依存する書き方になりますが、3.で示したSuccessHandlerにて実装を切り替えることがSpringの設定でも可能ですので、Controllerは認証環境に依存しない値をSuccessHandlerにてバインドした値から取得するようにすればControllerの依存度は低くなるでしょう。

投稿2017/06/27 13:03

A-pZ

総合スコア12011

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Youichi256

2017/06/29 03:04

1.ログイン状態の保持期間を1時間とかにしたい OAuthサービスプロバイダごとに専用のやり方が必要そうですが、他の問題が片付いたら検討してみます。 2.ユーザを一意に特定するのは ありがとうございます。公式情報を探したかったのです。 3.ログイン直後にユーザに関する情報をセッションに入れるタイミングがほしい 試してみましたが、ハンドラが呼ばれませんでした。ログインフォームにも仕掛けがいるようですので、OAuth2には対応していないのではないでしょうか。 4.Google以外でもOAuthで認証するときに困らないような書き方 OAuth2プロバイダごとの違いを吸収してくれるSpring Socialというのもあるみたいで、こちらも平行で調べています。
A-pZ

2017/06/29 11:37

そうですね、SpringSocial経由でTwitter認証やFacebook認証の機能を簡単に使えますので、独自に実装しなくて済むのであれば、提供ライブラリを使うのが良いと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問