移动端获得微信openid_构建用于移动设备的OpenID Connect流

移动端获得微信openid

Finding precise guidelines on how to implement OpenID Connect for native mobile apps is a harsh journey. Most resources available don’t follow best practices and the other ones leave some important questions unanswered.

寻找有关如何为本地移动应用程序实施OpenID Connect的精确指南是艰巨的旅程。 可用的大多数资源都没有遵循最佳实践,而其他资源则留下了一些重要问题未得到解答。

The goal here is not to reinvent the wheel, but to present a simple yet complete & robust implementation of OpenID Connect flow for mobile. It is based on the Authentication Code Flow, complies with the last official guidelines available RCF 8252 and IETF OAuth 2.0 Security Best Practices, and is fully compatible with the OpenID Connect Foundation Android SDK and OpenID Connect Foundation iOS SDK.

这里的目标不是重新发明轮子,而是提出一种简单而完整且健壮的针对移动设备的OpenID Connect流实现。 它基于身份验证代码流 ,符合最新的RCF 8252IETF OAuth 2.0安全最佳实践官方指南,并且与OpenID Connect Foundation Android SDKOpenID Connect Foundation iOS SDK完全兼容。

做出的选择 (Choices made)

Opinionated choices have been made for this implementation.

为此实现做出了有选择的选择。

1. Use the Authorization Code Grant flow

1.使用授权码授予流程

Given the vulnerability of the Implicit Grant flow, the Authorization Code Grant flow is the one that should be used from now on.

考虑到隐式授予流程脆弱性授权码授予流程是从现在开始应使用的流程。

2. Use the browser for authentication

2.使用浏览器进行身份验证

Thinking about an authentication flow on mobile, it is quite intuitive to go with a native implementation. However, keeping the authentication part in the browser helps you achieve important goals :

考虑到移动设备上的身份验证流程,采用本机实现非常直观。 但是,将身份验证部分保留在浏览器中可帮助您实现重要目标:

  • security: by going through the browser and using the web authentication form of the Authorization server, you instantly benefit from security mechanisms they may already implements (ie : sandboxing, certificates validation, …).

    安全性:通过浏览器并使用授权服务器的Web身份验证表单,您可以立即从它们可能已经实现的安全性机制(例如:沙箱,证书验证等)中受益。
  • user trust: you may think that a native implementation is always more efficient. However, from a user point of view, having to provide his third party credentials directly in your application seems like a potential security issue. How could he know that you are not going to steal his credentials along the way ?

    用户信任:您可能会认为本机实现总是效率更高。 但是,从用户的角度来看,必须直接在您的应用程序中提供第三方凭据似乎是潜在的安全问题。 他怎么会知道您一路上不会窃取他的证书?
  • maintainability: when authentication goes through the browser, the authentication flow is delegated to the Authorization server. So what happens if the authorization server wants to enforce new mechanisms (ie : 2-factors authentication, user consent, …) ? Nothing on your side. It will be completely transparent for your application.

    可维护性:通过浏览器进行身份验证时,身份验证流程将委派给授权服务器。 那么,如果授权服务器想要实施新的机制(即2要素身份验证,用户同意等),会发生什么? 什么都没有在你身边。 对于您的应用程序,它将是完全透明的。

3.采取简单的路径将client_secret保密 (3. Take a simple path to keep the client_secret secret)

Any secret bundled with a mobile application shouldn’t be considered a secret. AppAuth and RCF 8252 — section-5.3.3 emphasize this and state that to ensure that the client_secret should be kept server-side. Perfect, let's keep it server side but storing this secret in a "proxy" ! But as soon as you do that, you realize that without a strong authentication between your client application and your server, your client_secret will be kept secret but anybody can impersonate your application through your proxy. So any attacker catching the OAuth authentication "code" will be able to impersonate your app through your proxy and getting the user "access_token" from it.

与移动应用程序捆绑在一起的任何秘密都不应视为秘密。 AppAuthRCF 8252(第5.3.3节)强调了这一点,并声明应确保将client_secret保留在服务器端。 完美,让我们保留它在服务器端,但是将这个秘密存储在“代理”中! 但是,一旦您这样做,您就会意识到,如果没有在客户端应用程序和服务器之间进行强身份验证,则client_secret将会被保密,但是任何人都可以通过代理来模拟您的应用程序。 因此,任何捕获OAuth身份验证“代码”的攻击者都可以通过您的代理模仿您的应用,并从中获取用户“ access_token”。

Proof Key for Code Exchange (PKCE) has been created to prevent this without requiring a strong authentication between the client and the server. Used in conjunction with a mechanism preventing MITM attacks between your application and your server, client_secret will be able to be kept securely server-side while preventing anybody to perform a user authentication on your behalf.

已创建代码交换证明密钥(PKCE),以防止这种情况,而无需在客户端和服务器之间进行严格的身份验证。 与防止应用程序和服务器之间发生MITM攻击的机制结合使用, client_secret将能够安全地保留在服务器端,同时防止任何人代表您执行用户身份验证。

4.不支持一切 (4. Do not support everything)

Android App links and iOS Universal Links support is key to this implementation. They require Android >= 6.0 Marshmallow and iOS >= 9. Since both were released in 2015, this shouldn’t be too much of a problem by now.

Android App链接iOS Universal Links支持是此实现的关键。 他们需要Android> = 6.0 Marshmallow和iOS> =9。自从两者都于2015年发布以来,现在这应该不是太大的问题。

抽象流程 (Abstract Flow)

详细流程 (Detailed Flow)

Authentication is done in the browser by calling the authorize endpoint of the authorization server. This endpoint is often GET /authorize but it could be something else, depending on the authorization server configuration.

通过调用授权服务器的授权端点在浏览器中完成身份验证。 该端点通常是GET /authorize但也可以是其他端点,具体取决于授权服务器的配置。

GET <AUTHORIZATION_SERVER_URL>/authorize?
response_type=code
&scope=openid email profile
&client_id=<CLIENT_ID>
&redirect_uri=<REDIRECT_URI>
&code_challenge_method=S256
&code_challenge=<PKCE_CHALLENGE>

response_type As we are implementing the “Authorization Code Grant flow”, should always be code.

response_type在实现“授权代码授予流”时,应始终为code

scope Define the OpenID Connect claims you are interested about, see Requesting Claims using Scope Values.

scope定义您感兴趣的OpenID Connect声明,请参阅使用范围值请求声明

client_id The identifiers of your application for the authorization server.

client_id授权服务器的应用程序标识符。

redirect_uri A valid URL recognized by your mobile application as an app link. It will allow to redirect the user back to your application after authentication and to get the “code” back from the authentication process.

redirect_uri一个有效的URL,您的移动应用程序将其识别为应用程序链接。 它将在身份验证后将用户重定向回您的应用程序,并从身份验证过程中获取“代码”。

code_challenge_method PKCE code challenge method, S256 (SHA-256) MUST be used if the client supports it.

如果客户端支持,则必须使用code_challenge_method PKCE代码挑战方法S256 (SHA-256)。

code_challenge PKCE code challenge, see PKCE Protocol to implement it yourself or use AppAuth to handle it for you.

code_challenge PKCE代码质询,请参阅PKCE协议自行实现或使用AppAuth为您处理。

Security concerns

安全问题

  • This authentication process should be handled using a registered browser or an “in-app browser tabs”, not a “web-view” (see RFC 8252).

    应使用注册的浏览器或“应用内浏览器选项卡”而非“网络视图”(请参阅RFC 8252 )来处理此身份验证过程。

  • You should use Android app links and iOS universal links, so only your application is able to get the authorization callback through redirect_uri.

    您应该使用Android应用程序链接iOS通用链接 ,因此只有您的应用程序才能通过redirect_uri获取授权回调。

  • You may want to restrict which browser is allowed for this process, AppAuth provides a mechanism to control which browser is used for authorization.

    您可能想要限制此过程允许使用的浏览器,AppAuth提供了一种机制来控制使用哪个浏览器进行授权

  • If your authentication server does not support PKCE, the code_challenge and code_challenge_method parameters won't be supported. In this case, at least use the state parameter to prevent CSRF attacks (see https://tools.ietf.org/html/draft-ietf-oauth-security-topics-15#section-4.7.1).

    如果您的身份验证服务器不支持PKCE,则将不支持code_challengecode_challenge_method参数。 在这种情况下,请至少使用state参数来防止CSRF攻击(请参阅https://tools.ietf.org/html/draft-ietf-oauth-security-topics-15#section-4.7.1)。

2.获取令牌和索偿 (2. Getting token & claims)

We will now go through our application server. We define a POST /open_id_connect endpoint on our server for this purpose. This endpoint will exchange the given code (and code_verifier) with the access_token and the claims from the authorization server.

现在,我们将遍历我们的应用程序服务器。 POST /open_id_connect ,我们在服务器上定义了一个POST /open_id_connect端点。 该端点将与给定的code (和code_verifier )与access_token和来自授权服务器的claims交换。

POST <APP_SERVER_URL>/open_id_connect?
code=<CODE>
&code_verifier=<CODE_VERIFIER>

code The code returned by the authorization server to the redirect_uri on successful user authentication.

code成功进行用户身份验证时,授权服务器返回到redirect_uricode

code_verifier PKCE code_verifier that matches the code_challenge sent to the authorization server during authentication process.

code_verifier PKCE code_verifier的匹配code_challenge在认证过程中发送到授权服务器。

Response

响应

In our implementation we also add an account property that will provide info on the existing user account on the platform (if any).

在我们的实现中,我们还添加了一个account属性,该属性将提供有关平台上现有用户帐户(如果有)的信息。

Response (no account associated to these credentials)

响应(没有与这些凭据关联的帐户)

{
"access_token": "<oauth_access_token>",
"claims": {
"sub": "<oauth_sub>",
"email": "<oauth_email>",
"given_name": "<oauth_first_name>",
"family_name": "<oauth_last_name>"
},
"account": null
}

Response (associated account already exits)

响应(关联帐户已存在)

{
"access_token": "<oauth_access_token>",
"claims": {
"sub": "<oauth_sub>",
"email": "<oauth_email>",
"given_name": "<oauth_first_name>",
"family_name": "<oauth_last_name>"
},
"account": { ... }
}

Security concerns

安全问题

(2之二)。 获取令牌和索偿 ((2 bis). Getting token & claims)

Behind the scene, your app server will have to call the authentication server to gather info.

在后台,您的应用服务器将不得不调用身份验证服务器来收集信息。

Calling the token endpoint

调用令牌端点

This call will allow your app server to exchange the code with an access_token.

通过此调用,您的应用服务器可以与access_token交换code

curl -X POST '<AUTHORIZATION_SERVER_URL>/token' \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'grant_type=authorization_code' \
-d 'client_id=<CLIENT_ID>' \
-d 'client_secret=<CLIENT_SECRET>' \
-d 'redirect_uri=<REDIRECT_URI>' \
-d 'code=<CODE>' \
-d 'code_verifier=<PKCE_CODE_VERIFIER>'

Calling the userinfo endpoint

调用userinfo端点

This call will allow your app server to get the “claims” requested during authentication (giving the same scope parameter).

通过此调用,您的应用服务器可以获取身份验证期间请求的“声明”(提供相同的scope参数)。

curl -X POST '<AUTHORIZATION_SERVER_URL>/userinfo' \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-d 'client_id=<CLIENT_ID>' \
-d 'client_secret=<CLIENT_SECRET>' \
-d 'scope=openid profile email'

而已 ! (That’s it !)

You now know the end-user identity from the authorization server ( access_token and claims) and if the user is already registered on your server ( account). So you can decide if the end-user need a "sign-up" or a "sign-in", and use the gathered info to support these processes.

现在,您可以从授权服务器( access_tokenclaims )中了解最终用户的身份,以及该用户是否已经在您的服务器( account )上注册。 因此,您可以决定最终用户是否需要“注册”或“登录”,并使用收集的信息来支持这些过程。

Building a simple & secure OpenID Connect authentication flow on mobile is quite simple, if you follow the right guidelines ;-) Happy to answer any suggestions !

如果您遵循正确的准则,则在移动设备上构建简单且安全的OpenID Connect身份验证流程非常简单;-)乐意回答任何建议!

翻译自: https://medium.com/klaxit-techblog/openid-connect-for-mobile-apps-fcce3ec3472

移动端获得微信openid

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值