use jwt access-token on grails rest api
TRANSCRIPT
JWTトークン認証つきのWeb APIを作るのはGrails+Spring Security REST Pluginを使えば非常に簡単である件
JGGUG G*WS LT大会 2016/05/13
Copyright (C) 2016 NTT Software Corporation. All rights reserved.2
自己紹介
上原潤二(@uehaj)
NTTソフトウェア(株)Grails推進室
JGGUG運営委員
書籍:
プログラミングGROOVY(技評)
Grails徹底入門(翔泳社)
ブログ「Grな日々」
Copyright (C) 2016 NTT Software Corporation. All rights reserved. 3
Web APIの認証をどうする?
• セッション・クッキー
• トークンベース認証 ステートレススケーラブルクロスドメイン疎結合
Copyright (C) 2016 NTT Software Corporation. All rights reserved. 4
Web APIの認証をどうする?
• セッション・クッキー
• トークンベース認証– 払い出し方式
– 電子署名方式• OAuth2.0 アクセストークン
• 上記の簡易版としてのJWTアクセストークン使用
簡単
Copyright (C) 2016 NTT Software Corporation. All rights reserved. 5
JWT(JSON Web Token)
• Webアプリでclaimをうけわたすための仕様(URL-safe)
• OAuth2.0、OpenID Connectの要素技術
• 実体は電子署名+Base64されたJSON– Authorization: Bearer eyJhbGciOiJIUzI1….
• アクセストークンにも使用できる
• 利点–払い出したトークン値の保存管理が不要
–オフライン検証、第三者による検証
Copyright (C) 2016 NTT Software Corporation. All rights reserved.
Spring Security REST plugin
•6
JWTトークンによるAPI認証をデ
フォルトで提供
Copyright (C) 2016 NTT Software Corporation. All rights reserved.
以下の流れ
•まずはRESTサーバを動かす
•Spring Securityの設定
•アクセストークンを取得
•アクセストークンを使ってREST APIアクセス
7
Copyright (C) 2016 NTT Software Corporation. All rights reserved.
まずはRESTサーバを動かす(1)
$ grails create-app restapp3| Application created at ../restapp3$ cd restapp3$ mkdir -p grails-app/domain/sample$ cat << EOT > grails-app/domain/sample/Book.groovypackage sampleimport grails.rest.*
@Resourceclass Book {String titleint price
}
EOT
8
Copyright (C) 2016 NTT Software Corporation. All rights reserved.
まずはRESTサーバを動かす(2)URLMappinggrails-app/controllers/restapp3/UrlMappings.groovyに以下を追加
package restapp3:
static mappings = {"/api/books"(resources:"book")
9
Copyright (C) 2016 NTT Software Corporation. All rights reserved.
まずはRESTサーバを動かす(3)動作確認$ grails run-app$ curl http://localhost:8080/api/books.json[]
$ curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"title":"title", "price":100}' http://localhost:8080/api/books.json{"class":"sample.Book","id":2,"price":100,"title":"title"}
$ curl http://localhost:8080/api/books.json[{"class":"sample.Book","id":1,"price":100,"title":"title"}]
$ curl http://localhost:8080/api/books/1.json{"class":"sample.Book","id":1,"price":100,"title":"title"}
10
Copyright (C) 2016 NTT Software Corporation. All rights reserved.
Spring Securityの設定(1)
build.gradleのdependenciesに以下を設定
compile "org.grails.plugins:spring-security-core:3.0.3"compile "org.grails.plugins:spring-security-rest:2.0.0.M2“
11
Copyright (C) 2016 NTT Software Corporation. All rights reserved.
Spring Securityの設定(2)
$ grails run-app$ grails s2-quickstart sample User Role$ cat grails-app/conf/BootStrap.groovyimport sample.*class BootStrap {
def init = { servletContext ->def adminRole = new Role('ROLE_ADMIN').save()def userRole = new Role('ROLE_USER').save()def testUser = new User('me', 'password').save()UserRole.create testUser, adminRoleUserRole.withSession { it.flush(); it.clear() }assert User.count() == 1assert Role.count() == 2assert UserRole.count() == 1
}:
12
ユーザ・ロール情報をDB登録
Copyright (C) 2016 NTT Software Corporation. All rights reserved.
Spring Securityの設定(3)
grails-app/conf/application.groovy に以下を追加
grails.plugin.springsecurity.userLookup.userDomainClassName= 'sample.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName= 'sample.UserRole'
grails.plugin.springsecurity.authority.className= 'sample.Role'
grails.plugin.springsecurity.controllerAnnotations.staticRules= [[pattern:'/**', access:['ROLE_USER', 'ROLE_ADMIN']]]
grails.plugin.springsecurity.filterChain.chainMap= [[ pattern: '/api/**',
filters: 'JOINED_FILTERS,-anonymousAuthenticationFilter,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter‘ ],
[ pattern: '/**',filters: 'JOINED_FILTERS,-restTokenValidationFilter,-
restExceptionTranslationFilter‘ ]]
13
APIを呼ぶ権限その他の権限
Copyright (C) 2016 NTT Software Corporation. All rights reserved.
アクセストークンを取得
$ curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"username":"me", "password":"password"}' http://localhost:8080/api/login
{"username":"me","roles":["ROLE_ADMIN"],"token_type":"Bearer","access_token":"eyJhbGciOiJIUzI1…","expires_in":3600,"refresh_token":"eyJhbGc…"}
14
認証エンドポイント
アクセストークン(JWT)
リフレッシュトークン(JWT)
Copyright (C) 2016 NTT Software Corporation. All rights reserved.
アクセストークンを使ってREST APIアクセス$ curl -H “Accept: application/json” -H “Content-type: application/json” -H “Authorization: Bearer eyJhbGciOiJIUzI1…." -X GET http://localhost:8080/api/books.json
[{"id":1,"price":100,"title":"Book Title"}]
15
Copyright (C) 2016 NTT Software Corporation. All rights reserved.
まとめ
• GrailsでのREST API開発は超簡単
• JWT便利。メール認証などにも。
• トークン無効化が不要ならシンプル
• トークン無効化するにはexpire期限を指定しリフレッシュトークンで再発行
– http://stackoverflow.com/questions/19655911/request-new-access-token-using-refresh-token-in-username-password-grant-in-sprin
16
Copyright (C) 2016 NTT Software Corporation. All rights reserved.
参考リンク
• Grails3対応のSpring Securty RESTドキュメントhttp://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/
• Grails2対応のSpring Securty RESTドキュメントhttp://alvarosanchez.github.io/grails-spring-security-rest/1.5.3/docs/guide/index.html
• Grails 3でWeb APIを簡単に作ろう!https://speakerdeck.com/yamkazu/grails-3deweb-apiwojian-dan-nizuo-rou
17