Using Slack as Identity Provider with OpenID for Federated Identity Management with Aspnet Core App
-
I was looking for how to/docs on how to use Slack as an external identity provider using OpenID Connect within FusionAuth but was unable to find one.
After trial and error I did manage to have a start and would like a second opinion on how legit I did it. Here are all the repro steps :
-
I created an app on Slack : https://api.slack.com/apps. All left to default value except tab "OAuth & Permissions", I add redirect URL for my FusionAuth test server (like http://localhost:9011/oauth2/callback).
-
I created an OpenID Connect Identity Providers via FusionAuth Admin interface (Home/Settings/Identity Providers/Add Provider) with those values :
- Client ID : from https://api.slack.com/apps
- Client authentication method : Request body (client_secret_post)
- Client secret : from https://api.slack.com/apps
- Authorization endpoint : https://slack.com/oauth/authorize (I tried hard make it work with v2 but was unable to succeed, something with the user_scope vs scope that slack's api v2 is asking to manage bot) took from here https://api.slack.com/methods/oauth.access
- Token endpoint : https://slack.com/api/oauth.access took from https://api.slack.com/specs/openapi/v2/slack_web.json field "tokenUrl" corresponding to the oauth/authorize endpoint
- Userinfo endpoint : https://slack.com/api/users.profile.get took from https://api.slack.com/methods/users.profile.get because it seemed to give the email with the oauth scope I was able to pass.
- Use POST Method : nope
- Reconcile Lambda : Custom one, back to it at step 3
- Scope : users.profile:read took from https://api.slack.com/legacy/oauth-scopes (it took me a while to understand the difference between slack's scope https://api.slack.com/scopes from the oauth-scopes, but even with the current scope I can only give one scope at a time)
- Email claim : email (didn't manage to get it work, I used a lambda to reconcile)
- Managed domains : empty
- Debug enabler : BIG yes, so usefull in dev
- Applications : Create Registration & Enabled both to yes
- I created a Lambda for OpenID Connect Reconcile :
function reconcile(user, registration, jwt) { user.fullName = jwt.profile.real_name_normalized; user.imageUrl = jwt.profile.image_192; user.email = jwt.profile.email; registration.username = jwt.profile.real_name_normalized; }
-
Of course update the Identity Provider to use that reconcile lambda.
-
Now time to use it in a test aspnet app based from https://github.com/FusionAuth/fusionauth-example-asp-netcore
I change the AddOpenIdConnect call in Startup.cs to :
.AddOpenIdConnect("oidc", options => { options.Authority = Configuration["SampleApp:Authority"]; options.ClientId = Configuration["SampleApp:ClientId"]; options.ClientSecret = "SUCH SECRET"; options.TokenValidationParameters = new TokenValidationParameters { IssuerSigningKeyResolver = (token, securityToken, kid, parameters) => { var client = new HttpClient(); var response = client.GetAsync("http://localhost:9011/.well-known/jwks.json").Result; var responseString = response.Content.ReadAsStringAsync().Result; var keys = JsonConvert.DeserializeObject<JwkList>(responseString); return keys.Keys; }, ValidIssuers = new List<string> { "acme.com" } }; options.ResponseType = "code"; options.RequireHttpsMetadata = false; });
- I changed the RequirePermission in Startup.cs, didn't manage to get applicationId in my claims (default permission)
services.AddAuthorization(options => { options.AddPolicy("Registered", policy => policy.RequireAssertion(c => { var result = c.User.Claims.Any(); return result; })); });
After that I'm able to authenticate on slack, to give permission to get my identity and then to login in my test aspnet
sub : 9bc2f6ae-23d1-4d12-97c9-db3bd1885918 jti : 6b163068-9bd6-4e58-ada5-922991f3f1ef authenticationType : OPENID_CONNECT email : much@mail.com email_verified : true sid : 4730abf3-ff80-4b23-b83d-bcc16fb60fb7
First did I miss a good doc/post somewhere explaining how to use slack as an Identity Provider ?
Second what I could have done wrong, how to correct it ?
Then does someone manage to get it work with slack's oauth v2 api ?
Last why do I have to give permission again & again when I login ? -
-
First did I miss a good doc/post somewhere explaining how to use slack as an Identity Provider ?
Nope, sorry, we haven't documented that yet.
Second what I could have done wrong, how to correct it ?
I'm unsure. In fact, I'm sorry, from reading this it sounds like you've got it working (except having to give permissions multiple times). What am I missing?
Then does someone manage to get it work with slack's oauth v2 api ?
I have not heard of anyone doing this successfully.
Last why do I have to give permission again & again when I login ?
I'm not sure why Slack would require that again and again. Is the token being stored in the registration object? You can see this if you look at the user and then look at the source tab.
Do you have the docs for the slack OIDC identity provider handy? Have you seen if anyone else is seeing this behavior?
-
We've managed to get "Sign in with Slack" to work using the following settings:
Client authentication: Request body (client_secret_post)
Authorization endpoint: https://slack.com/openid/connect/authorize
Token endpoint: https://slack.com/api/openid.connect.token
Userinfo endpoint: https://slack.com/api/openid.connect.userInfo
Scope: openid email profile
Linking strategy: Link on email. Create the user if they do not exist.
Reconcile lambda: Default OpenID Connect Reconcile provided by FusionAuth -
@eirikur That is awesome, thanks so much for sharing your settings.