Merge pull request #2090 from velias/KEYCLOAK-2348
KEYCLOAK-2348 - Social login provider for Microsoft account - KC master branch
This commit is contained in:
commit
e71ac6f1b3
9 changed files with 260 additions and 5 deletions
|
@ -211,7 +211,7 @@
|
||||||
<para>
|
<para>
|
||||||
Social providers allows you to enable social authentication to your realm.
|
Social providers allows you to enable social authentication to your realm.
|
||||||
Keycloak makes it easy to let users log in to your application using an existing account with a social network.
|
Keycloak makes it easy to let users log in to your application using an existing account with a social network.
|
||||||
Currently Facebook, Google, Twitter, GitHub, LinkedIn and StackOverflow are supported with more planned for the future.
|
Currently Facebook, Google, Twitter, GitHub, LinkedIn, Microsoft and StackOverflow are supported with more planned for the future.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -357,7 +357,7 @@
|
||||||
So is trying to remember yet another username and password combination.
|
So is trying to remember yet another username and password combination.
|
||||||
Social identity providers makes it easy for users to register on your realm and quickly sign in using a social network.
|
Social identity providers makes it easy for users to register on your realm and quickly sign in using a social network.
|
||||||
Keycloak provides built-in support for the most common social networks out there, such as Google, Facebook, Twitter,
|
Keycloak provides built-in support for the most common social networks out there, such as Google, Facebook, Twitter,
|
||||||
Github, LinkedId and StackOverflow.
|
Github, LinkedId, Microsoft and StackOverflow.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
|
@ -855,6 +855,95 @@
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
</section>
|
</section>
|
||||||
|
<section>
|
||||||
|
<title>Microsoft</title>
|
||||||
|
<para>
|
||||||
|
To enable login with Microsoft account you first have to register an OAuth application on
|
||||||
|
<ulink url="https://account.live.com/developers/applications/index">Microsoft account Developer Center</ulink>. Then you need to copy the client id and secret into the Keycloak Admin Console.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Let's see first how to create an application with Microsoft.
|
||||||
|
</para>
|
||||||
|
<orderedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Go to <ulink url="https://account.live.com/developers/applications/create">create new application on Microsoft account Developer Center</ulink> url and login here.
|
||||||
|
Use any value for <literal>Application Name</literal>, <literal>Application Logo</literal> and <literal>URLs</literal> you want.
|
||||||
|
In <literal>API Settings</literal> set <literal>Target Domain</literal> to the domain where your Keycloak instance runs.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Copy <literal>Client Id</literal> and <literal>Client Secret</literal> from <literal>App Settings</literal> page.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
|
<para>
|
||||||
|
Now that you have the client id and secret you can proceed with the creation of a Microsoft Identity Provider in Keycloak. As follows:
|
||||||
|
</para>
|
||||||
|
<orderedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Select the <literal>Microsoft</literal> identity provider from the drop-down box on the top right corner of the identity providers table in Keycloak's Admin Console. You should be presented with a specific page to configure the selected provided.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Copy the client id and client secret to their corresponding fields in the Keycloak Admin Console. Click <literal>Save</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
|
<para>
|
||||||
|
Once you create the identity provider in Keycloak, you must update your Microsoft application with the redirect url that was
|
||||||
|
generated to your identity provider.
|
||||||
|
</para>
|
||||||
|
<orderedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Open the Microsoft account Developer Center and select <literal>API Settings</literal> of your application. In <literal>Redirect URLs</literal>
|
||||||
|
insert the redirect uri created by Keycloak. The redirect uri
|
||||||
|
usually have the following format: <literal>http://{host}:{port}/auth/realms/{realm}/broker/microsoft/endpoint</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
You can always get the redirect url for a specific identity provider from the table presented when you
|
||||||
|
click on the 'Identity Provider' tab in <emphasis>Realm > Settings</emphasis>.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
<para>
|
||||||
|
That is it! This pretty much what you need to do in order to setup this identity provider.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The table below lists some additional configuration options you may use when configuring this provider.
|
||||||
|
</para>
|
||||||
|
<table>
|
||||||
|
<title>Configuration Options</title>
|
||||||
|
<tgroup align="left" cols="2">
|
||||||
|
<thead>
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
Configuration
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
Description
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
</thead>
|
||||||
|
<tbody valign="top">
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
<literal>Default Scopes</literal>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
Allows you to manually specify the scopes that users must authorize when authenticating with this provider. For a complete list of scopes, please take a look at <ulink url="https://msdn.microsoft.com/en-us/library/hh243646.aspx">https://msdn.microsoft.com/en-us/library/hh243646.aspx</ulink>. By default, Keycloak uses the following scopes: <literal>wl.basic,wl.emails</literal>
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</table>
|
||||||
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<title>StackOverflow</title>
|
<title>StackOverflow</title>
|
||||||
<para>
|
<para>
|
||||||
|
@ -1282,7 +1371,7 @@ keycloak.createLoginUrl({
|
||||||
<section>
|
<section>
|
||||||
<title>Mapping/Importing User profile data from Social Identity Provider</title>
|
<title>Mapping/Importing User profile data from Social Identity Provider</title>
|
||||||
<para>
|
<para>
|
||||||
You can import user profile data provided by social identity providers like Google, GitHub, LinkedIn, Stackoverflow and Facebook
|
You can import user profile data provided by social identity providers like Google, GitHub, LinkedIn, Microsoft, Stackoverflow and Facebook
|
||||||
into new Keycloak user created from given social accounts. After you configure a broker, you'll see a <literal>Mappers</literal>
|
into new Keycloak user created from given social accounts. After you configure a broker, you'll see a <literal>Mappers</literal>
|
||||||
button appear. Click on that and you'll get to the list of mappers that are assigned to this broker. There is a
|
button appear. Click on that and you'll get to the list of mappers that are assigned to this broker. There is a
|
||||||
<literal>Create</literal> button on this page. Clicking on this create button allows you to create a broker mapper.
|
<literal>Create</literal> button on this page. Clicking on this create button allows you to create a broker mapper.
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
package org.keycloak.social.microsoft;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
import org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider;
|
||||||
|
import org.keycloak.broker.oidc.OAuth2IdentityProviderConfig;
|
||||||
|
import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper;
|
||||||
|
import org.keycloak.broker.oidc.util.JsonSimpleHttp;
|
||||||
|
import org.keycloak.broker.provider.BrokeredIdentityContext;
|
||||||
|
import org.keycloak.broker.provider.IdentityBrokerException;
|
||||||
|
import org.keycloak.broker.provider.util.SimpleHttp;
|
||||||
|
import org.keycloak.broker.social.SocialIdentityProvider;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Identity provider for Microsoft account. Uses OAuth 2 protocol of Windows Live Services as documented at <a href="https://msdn.microsoft.com/en-us/library/hh243647.aspx">https://msdn.microsoft.com/en-us/library/hh243647.aspx</a>
|
||||||
|
*
|
||||||
|
* @author Vlastimil Elias (velias at redhat dot com)
|
||||||
|
*/
|
||||||
|
public class MicrosoftIdentityProvider extends AbstractOAuth2IdentityProvider implements SocialIdentityProvider {
|
||||||
|
|
||||||
|
private static final Logger log = Logger.getLogger(MicrosoftIdentityProvider.class);
|
||||||
|
|
||||||
|
public static final String AUTH_URL = "https://login.live.com/oauth20_authorize.srf";
|
||||||
|
public static final String TOKEN_URL = "https://login.live.com/oauth20_token.srf";
|
||||||
|
public static final String PROFILE_URL = "https://apis.live.net/v5.0/me";
|
||||||
|
public static final String DEFAULT_SCOPE = "wl.basic,wl.emails";
|
||||||
|
|
||||||
|
public MicrosoftIdentityProvider(OAuth2IdentityProviderConfig config) {
|
||||||
|
super(config);
|
||||||
|
config.setAuthorizationUrl(AUTH_URL);
|
||||||
|
config.setTokenUrl(TOKEN_URL);
|
||||||
|
config.setUserInfoUrl(PROFILE_URL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BrokeredIdentityContext doGetFederatedIdentity(String accessToken) {
|
||||||
|
try {
|
||||||
|
String URL = PROFILE_URL + "?access_token=" + URLEncoder.encode(accessToken, "UTF-8");
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Microsoft Live user profile request to: " + URL);
|
||||||
|
}
|
||||||
|
JsonNode profile = JsonSimpleHttp.asJson(SimpleHttp.doGet(URL));
|
||||||
|
|
||||||
|
String id = getJsonProperty(profile, "id");
|
||||||
|
|
||||||
|
String email = null;
|
||||||
|
if (profile.has("emails")) {
|
||||||
|
email = getJsonProperty(profile.get("emails"), "preferred");
|
||||||
|
}
|
||||||
|
|
||||||
|
BrokeredIdentityContext user = new BrokeredIdentityContext(id);
|
||||||
|
|
||||||
|
user.setUsername(email != null ? email : id);
|
||||||
|
user.setFirstName(getJsonProperty(profile, "first_name"));
|
||||||
|
user.setLastName(getJsonProperty(profile, "last_name"));
|
||||||
|
if (email != null)
|
||||||
|
user.setEmail(email);
|
||||||
|
user.setIdpConfig(getConfig());
|
||||||
|
user.setIdp(this);
|
||||||
|
|
||||||
|
AbstractJsonUserAttributeMapper.storeUserProfileForMapper(user, profile, getConfig().getAlias());
|
||||||
|
|
||||||
|
return user;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IdentityBrokerException("Could not obtain user profile from Microsoft Live ID.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getDefaultScopes() {
|
||||||
|
return DEFAULT_SCOPE;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
*
|
||||||
|
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.keycloak.social.microsoft;
|
||||||
|
|
||||||
|
import org.keycloak.broker.oidc.OAuth2IdentityProviderConfig;
|
||||||
|
import org.keycloak.broker.provider.AbstractIdentityProviderFactory;
|
||||||
|
import org.keycloak.broker.social.SocialIdentityProviderFactory;
|
||||||
|
import org.keycloak.models.IdentityProviderModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlastimil Elias (velias at redhat dot com)
|
||||||
|
*/
|
||||||
|
public class MicrosoftIdentityProviderFactory extends AbstractIdentityProviderFactory<MicrosoftIdentityProvider> implements SocialIdentityProviderFactory<MicrosoftIdentityProvider> {
|
||||||
|
|
||||||
|
public static final String PROVIDER_ID = "microsoft";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Microsoft";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MicrosoftIdentityProvider create(IdentityProviderModel model) {
|
||||||
|
return new MicrosoftIdentityProvider(new OAuth2IdentityProviderConfig(model));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return PROVIDER_ID;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
|
||||||
|
* as indicated by the @authors tag. All rights reserved.
|
||||||
|
*/
|
||||||
|
package org.keycloak.social.microsoft;
|
||||||
|
|
||||||
|
import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User attribute mapper.
|
||||||
|
*
|
||||||
|
* @author Vlastimil Elias (velias at redhat dot com)
|
||||||
|
*/
|
||||||
|
public class MicrosoftUserAttributeMapper extends AbstractJsonUserAttributeMapper {
|
||||||
|
|
||||||
|
private static final String[] cp = new String[] { MicrosoftIdentityProviderFactory.PROVIDER_ID };
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getCompatibleProviders() {
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return "microsoft-user-attribute-mapper";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -12,4 +12,5 @@ org.keycloak.social.facebook.FacebookUserAttributeMapper
|
||||||
org.keycloak.social.github.GitHubUserAttributeMapper
|
org.keycloak.social.github.GitHubUserAttributeMapper
|
||||||
org.keycloak.social.google.GoogleUserAttributeMapper
|
org.keycloak.social.google.GoogleUserAttributeMapper
|
||||||
org.keycloak.social.linkedin.LinkedInUserAttributeMapper
|
org.keycloak.social.linkedin.LinkedInUserAttributeMapper
|
||||||
org.keycloak.social.stackoverflow.StackoverflowUserAttributeMapper
|
org.keycloak.social.stackoverflow.StackoverflowUserAttributeMapper
|
||||||
|
org.keycloak.social.microsoft.MicrosoftUserAttributeMapper
|
||||||
|
|
|
@ -3,4 +3,5 @@ org.keycloak.social.github.GitHubIdentityProviderFactory
|
||||||
org.keycloak.social.google.GoogleIdentityProviderFactory
|
org.keycloak.social.google.GoogleIdentityProviderFactory
|
||||||
org.keycloak.social.linkedin.LinkedInIdentityProviderFactory
|
org.keycloak.social.linkedin.LinkedInIdentityProviderFactory
|
||||||
org.keycloak.social.stackoverflow.StackoverflowIdentityProviderFactory
|
org.keycloak.social.stackoverflow.StackoverflowIdentityProviderFactory
|
||||||
org.keycloak.social.twitter.TwitterIdentityProviderFactory
|
org.keycloak.social.twitter.TwitterIdentityProviderFactory
|
||||||
|
org.keycloak.social.microsoft.MicrosoftIdentityProviderFactory
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<div data-ng-include data-src="resourceUrl + '/partials/realm-identity-provider-social.html'"></div>
|
|
@ -201,6 +201,9 @@ ol#kc-totp-settings li:first-of-type {
|
||||||
.zocial.facebook,
|
.zocial.facebook,
|
||||||
.zocial.github,
|
.zocial.github,
|
||||||
.zocial.google,
|
.zocial.google,
|
||||||
|
.zocial.microsoft,
|
||||||
|
.zocial.stackoverflow,
|
||||||
|
.zocial.linkedin,
|
||||||
.zocial.twitter {
|
.zocial.twitter {
|
||||||
background-image: none;
|
background-image: none;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
@ -222,10 +225,18 @@ ol#kc-totp-settings li:first-of-type {
|
||||||
.zocial.facebook:hover,
|
.zocial.facebook:hover,
|
||||||
.zocial.github:hover,
|
.zocial.github:hover,
|
||||||
.zocial.google:hover,
|
.zocial.google:hover,
|
||||||
|
.zocial.microsoft:hover,
|
||||||
|
.zocial.stackoverflow:hover,
|
||||||
|
.zocial.linkedin:hover,
|
||||||
.zocial.twitter:hover {
|
.zocial.twitter:hover {
|
||||||
background-image: linear-gradient(rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0.2) 100%) !important;
|
background-image: linear-gradient(rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0.2) 100%) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Copy of zocial windows classes to be used for microsoft's social provider button */
|
||||||
|
.zocial.microsoft {background-color: #0052a4; color: #fff;}
|
||||||
|
.zocial.microsoft:before { content: "\f15d"; }
|
||||||
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
#kc-container-wrapper {
|
#kc-container-wrapper {
|
||||||
bottom: 13%;
|
bottom: 13%;
|
||||||
|
|
Loading…
Reference in a new issue