29 |
30 |
61 |
62 |
--------------------------------------------------------------------------------
/samples/webapp-spring-boot-saml2/src/main/java/com/omnissa/idm/samples/saml/core/CurrentUserHandlerMethodArgumentResolver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vincenzo De Notaris
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.omnissa.idm.samples.saml.core;
18 |
19 | import java.security.Principal;
20 |
21 | import org.springframework.core.MethodParameter;
22 | import org.springframework.security.core.Authentication;
23 | import org.springframework.security.core.userdetails.User;
24 | import org.springframework.stereotype.Component;
25 | import org.springframework.web.bind.support.WebArgumentResolver;
26 | import org.springframework.web.bind.support.WebDataBinderFactory;
27 | import org.springframework.web.context.request.NativeWebRequest;
28 | import org.springframework.web.method.support.HandlerMethodArgumentResolver;
29 | import org.springframework.web.method.support.ModelAndViewContainer;
30 |
31 | import com.omnissa.idm.samples.saml.stereotypes.CurrentUser;
32 |
33 | @Component
34 | public class CurrentUserHandlerMethodArgumentResolver implements
35 | HandlerMethodArgumentResolver {
36 |
37 | public boolean supportsParameter(MethodParameter methodParameter) {
38 | return methodParameter.getParameterAnnotation(CurrentUser.class) != null
39 | && methodParameter.getParameterType().equals(User.class);
40 | }
41 |
42 | public Object resolveArgument(MethodParameter methodParameter,
43 | ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
44 | WebDataBinderFactory binderFactory) throws Exception {
45 | if (this.supportsParameter(methodParameter)) {
46 | Principal principal = (Principal) webRequest.getUserPrincipal();
47 | return (User) ((Authentication) principal).getPrincipal();
48 | } else {
49 | return WebArgumentResolver.UNRESOLVED;
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/samples/DynamicRegistrationAppAuthDemo-Android/app/src/test/java/net/openid/appauth/OmnissaAppAuthTest.java:
--------------------------------------------------------------------------------
1 | package net.openid.appauth;
2 |
3 | import android.net.Uri;
4 |
5 | /**
6 | * Common class to hold test values.
7 | */
8 | public class OmnissaAppAuthTest {
9 |
10 | public static final Uri TEST_IDP_TOKEN_ENDPOINT =
11 | Uri.parse("https://testidp.example.com/authorize");
12 | public static final Uri TEST_IDP_AUTH_ENDPOINT = Uri.parse("https://testidp.example.com/token");
13 | public static final Uri TEST_IDP_ACTIVATION_ENDPOINT =
14 | Uri.parse("https://testidp.example.com/activate");
15 | public static final Uri TEST_IDP_REGISTRATION_ENDPOINT =
16 | Uri.parse("https://testidp.example.com/register");
17 |
18 | public static final String TEST_ACTIVATION_CODE = "activation-code";
19 | public static final String TEST_AUTHORIZATION_CODE = "authorization-code";
20 |
21 | public static final Uri TEST_APP_REDIRECT_URI = Uri.parse("test://my-redirect-uri");
22 | public static final String TEST_APP_SCHEME = "test";
23 |
24 | public static final String TEST_DEVICE_NAME = "device name";
25 | public static final String TEST_USER_DEVICE_JSON = "{ \"info\" : \"user_device\" }";
26 | public static final String TEST_APP_TEMPLATE = "app_template";
27 | public static final String TEST_SCOPE = "scope";
28 | public static final String TEST_STATE = "state";
29 | public static final String TEST_CLIENT_ID = "client_id";
30 | public static final String TEST_CLIENT_SECRET = "the_client_secret";
31 |
32 |
33 | public static AuthorizationServiceConfiguration getTestServiceConfig() {
34 | return new AuthorizationServiceConfiguration(
35 | TEST_IDP_AUTH_ENDPOINT,
36 | TEST_IDP_TOKEN_ENDPOINT,
37 | TEST_IDP_REGISTRATION_ENDPOINT);
38 | }
39 |
40 | public static DeviceActivationRequest getTestDeviceActivationRequest() {
41 | return new DeviceActivationRequest.Builder(TEST_IDP_ACTIVATION_ENDPOINT,
42 | getTestServiceConfig(), TEST_ACTIVATION_CODE).build();
43 |
44 | }
45 |
46 | public static DeviceRegistrationRequest.Builder getTestDeviceRegistrationRequestBuilder() {
47 | return new DeviceRegistrationRequest.Builder(getTestServiceConfig(), TEST_APP_REDIRECT_URI,
48 | TEST_DEVICE_NAME, TEST_USER_DEVICE_JSON, TEST_APP_TEMPLATE,
49 | TEST_IDP_ACTIVATION_ENDPOINT).setState(TEST_STATE);
50 |
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Omnissa Identity Manager
2 |
3 | Identity Manager is an Identity as a Service (IDaaS) offering, providing application provisioning, self-service catalog, conditional access controls and Single Sign-On (SSO) for SaaS, web, cloud and native mobile applications.
4 |
5 | ## Overview
6 |
7 | If you don't know where to start, read the introduction on existing protocols to achieve Single-Sign On with your application:
8 |
9 | * [Choosing the right authentication protocol](https://github.com/omnissa-archive/idm/wiki/Choosing-The-Right-Auth)
10 |
11 | ## How-To Guides
12 |
13 | The wiki contains a lot of documentation to help you achieve your task. Whether you want to have end-users login to your web application or mobile application, or have your service be able to call Omnissa Identity Manager API, read through the following guides:
14 |
15 | * [Integrating your web app with OAuth2.0 (end users log in)](https://github.com/omnissa-archive/idm/wiki/Integrating-Webapp-with-OAuth2)
16 | * [Integrating your mobile app with OAuth2.0 (end users log in)](https://github.com/omnissa-archive/idm/wiki/Single-sign-on-for-Mobile)
17 | * [Integrating your backend app with OAuth2.0 (service to service)](https://github.com/omnissa-archive/idm/wiki/Integrating-Client-Credentials-app-with-OAuth2)
18 | * [Validate the tokens](https://github.com/omnissa-archive/idm/wiki/Validating-Access-or-ID-Token)
19 | * [Managing Users and Groups using SCIM API](https://github.com/omnissa-archive/idm/wiki/SCIM-guide)
20 |
21 |
22 | ## Samples
23 | [](https://travis-ci.org/omnissa/idm/)
24 | Sample applications are provided - as is - to demonstrate how to integrate your application with Omnissa Identity Manager:
25 |
26 | * [Android application using the AppAuth library](https://github.com/omnissa-archive/idm/tree/master/samples/DynamicRegistrationAppAuthDemo-Android)
27 | * [SpringBoot web application using OAuth2.0](https://github.com/omnissa-archive/idm/tree/master/samples/webapp-spring-boot-oauth2)
28 | * [SpringBoot web application acting as a resource server using OAuth2.0](https://github.com/omnissa-archive/idm/tree/master/samples/webapp-spring-boot-oauth2-resource-server)
29 | * [SpringBoot web application using SAML2](https://github.com/omnissa-archive/idm/tree/master/samples/webapp-spring-boot-saml2)
30 |
31 | ## Resources
32 | * [Reference API File](https://github.com/omnissa-archive/idm/blob/master/apidocs/swagger.json)
33 | * [Identity Manager API Documentation](https://omnissa-archive.github.io/idm/api-docs)
34 |
--------------------------------------------------------------------------------
/samples/webapp-spring-boot-saml2/src/main/java/com/omnissa/idm/samples/saml/core/SAMLUserDetailsServiceImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vincenzo De Notaris
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.omnissa.idm.samples.saml.core;
18 |
19 | import org.slf4j.Logger;
20 | import org.slf4j.LoggerFactory;
21 | import org.springframework.security.core.GrantedAuthority;
22 | import org.springframework.security.core.authority.SimpleGrantedAuthority;
23 | import org.springframework.security.core.userdetails.User;
24 | import org.springframework.security.core.userdetails.UsernameNotFoundException;
25 | import org.springframework.security.saml.SAMLCredential;
26 | import org.springframework.security.saml.userdetails.SAMLUserDetailsService;
27 | import org.springframework.stereotype.Service;
28 |
29 | import java.util.ArrayList;
30 | import java.util.List;
31 |
32 | @Service
33 | public class SAMLUserDetailsServiceImpl implements SAMLUserDetailsService {
34 |
35 | // Logger
36 | private static final Logger LOG = LoggerFactory.getLogger(SAMLUserDetailsServiceImpl.class);
37 |
38 | public Object loadUserBySAML(SAMLCredential credential)
39 | throws UsernameNotFoundException {
40 |
41 | // The method is supposed to identify local account of user referenced by
42 | // data in the SAML assertion and return UserDetails object describing the user.
43 |
44 | String userID = credential.getNameID().getValue();
45 |
46 | LOG.info(userID + " is logged in");
47 | List authorities = new ArrayList();
48 | GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
49 | authorities.add(authority);
50 |
51 | // In a real scenario, this implementation has to locate user in a arbitrary
52 | // dataStore based on information present in the SAMLCredential and
53 | // returns such a date in a form of application specific UserDetails object.
54 | return new User(userID, "", true, true, true, true, authorities);
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/samples/DynamicRegistrationAppAuthDemo-Android/app/src/test/java/net/openid/appauth/DeviceActivationResponseTest.java:
--------------------------------------------------------------------------------
1 | package net.openid.appauth;
2 |
3 | import org.json.JSONObject;
4 | import org.junit.Before;
5 | import org.junit.Test;
6 | import org.junit.experimental.runners.Enclosed;
7 | import org.junit.runner.RunWith;
8 | import org.robolectric.RobolectricTestRunner;
9 | import org.robolectric.annotation.Config;
10 |
11 | import static net.openid.appauth.DeviceActivationResponse.PARAM_CLIENT_ID;
12 | import static net.openid.appauth.DeviceActivationResponse.PARAM_CLIENT_SECRET;
13 | import static org.assertj.core.api.Assertions.assertThat;
14 |
15 | /**
16 | * Unit test for the @{link DeviceActivationResponse} class.
17 | */
18 | @RunWith(RobolectricTestRunner.class)
19 | @Config(constants = com.omnissa.idm.samples.appauth.BuildConfig.class, sdk = 16)
20 | public class DeviceActivationResponseTest extends OmnissaAppAuthTest {
21 |
22 | private static final Object TEST_CLIENT_ID = "client_id";
23 | private static final Object TEST_CLIENT_SECRET = "client_secret";
24 |
25 | private static final String TEST_JSON = "{\n"
26 | + " \"client_id\": \"" + TEST_CLIENT_ID + "\"}";
27 |
28 | private DeviceActivationResponse.Builder mMinimalBuilder;
29 | private JSONObject mJson;
30 |
31 | @Before
32 | public void setUp() throws Exception {
33 | mJson = new JSONObject(TEST_JSON);
34 | mMinimalBuilder =
35 | new DeviceActivationResponse.Builder(getTestDeviceActivationRequest());
36 | }
37 |
38 | @Test(expected = IllegalArgumentException.class)
39 | public void testBuilderSetEmptyClientId() {
40 | mMinimalBuilder.setClientId("");
41 | }
42 |
43 | @Test
44 | public void testFromJson() throws Exception {
45 | DeviceActivationResponse response =
46 | new DeviceActivationResponse.Builder(getTestDeviceActivationRequest())
47 | .fromResponseJson(mJson).build();
48 | assertThat(response.clientId).isEqualTo(TEST_CLIENT_ID);
49 | }
50 |
51 | @Test
52 | public void testFromJsonWithClientSecret() throws Exception {
53 | mJson.put(PARAM_CLIENT_SECRET, TEST_CLIENT_SECRET);
54 | DeviceActivationResponse response =
55 | new DeviceActivationResponse.Builder(getTestDeviceActivationRequest())
56 | .fromResponseJson(mJson).build();
57 |
58 | assertThat(response.clientId).isEqualTo(TEST_CLIENT_ID);
59 | assertThat(response.clientSecret).isEqualTo(TEST_CLIENT_SECRET);
60 | }
61 |
62 |
63 | }
--------------------------------------------------------------------------------
/samples/DynamicRegistrationAppAuthDemo-Android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
14 |
16 |
17 |
18 |
19 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/samples/webapp-spring-boot-saml2/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/samples/DynamicRegistrationAppAuthDemo-Android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/samples/webapp-spring-boot-saml2/src/main/java/com/omnissa/idm/samples/saml/controllers/SSOController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vincenzo De Notaris
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.omnissa.idm.samples.saml.controllers;
18 |
19 | import org.slf4j.Logger;
20 | import org.slf4j.LoggerFactory;
21 | import org.springframework.beans.factory.annotation.Autowired;
22 | import org.springframework.security.authentication.AnonymousAuthenticationToken;
23 | import org.springframework.security.core.context.SecurityContextHolder;
24 | import org.springframework.security.saml.metadata.MetadataManager;
25 | import org.springframework.stereotype.Controller;
26 | import org.springframework.ui.Model;
27 | import org.springframework.web.bind.annotation.RequestMapping;
28 | import org.springframework.web.bind.annotation.RequestMethod;
29 |
30 | import javax.servlet.http.HttpServletRequest;
31 | import java.util.Set;
32 |
33 | @Controller
34 | @RequestMapping("/saml")
35 | public class SSOController {
36 |
37 | // Logger
38 | private static final Logger LOG = LoggerFactory
39 | .getLogger(SSOController.class);
40 |
41 | @Autowired
42 | private MetadataManager metadata;
43 |
44 | @RequestMapping(value = "/idpSelection", method = RequestMethod.GET)
45 | public String idpSelection(HttpServletRequest request, Model model) {
46 | if (!(SecurityContextHolder.getContext().getAuthentication() instanceof AnonymousAuthenticationToken)) {
47 | LOG.warn("The current user is already logged.");
48 | return "redirect:/landing";
49 | } else {
50 | if (isForwarded(request)) {
51 | Set idps = metadata.getIDPEntityNames();
52 | for (String idp : idps)
53 | LOG.info("Configured Identity Provider for SSO: " + idp);
54 | model.addAttribute("idps", idps);
55 | return "saml/idpselection";
56 | } else {
57 | LOG.warn("Direct accesses to '/idpSelection' route are not allowed");
58 | return "redirect:/";
59 | }
60 | }
61 | }
62 |
63 | /*
64 | * Checks if an HTTP request has been forwarded by a servlet.
65 | */
66 | private boolean isForwarded(HttpServletRequest request){
67 | if (request.getAttribute("javax.servlet.forward.request_uri") == null)
68 | return false;
69 | else
70 | return true;
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/samples/webapp-spring-boot-oauth2-resource-server/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.omnissa.idm.samples
7 | webapp-spring-boot-oauth2-resource-server
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | webapp-spring-boot-oauth2-resource-server
12 | Demo project for Spring Boot and Omnissa OAuth2
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 1.4.0.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | 1.8
24 |
25 |
26 |
27 |
28 | org.springframework.boot
29 | spring-boot-starter-actuator
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-security
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-starter-web
38 |
39 |
40 | org.springframework.security.oauth
41 | spring-security-oauth2
42 |
43 |
44 | org.springframework.security
45 | spring-security-jwt
46 | 1.0.5.RELEASE
47 |
48 |
49 | org.springframework.boot
50 | spring-boot-starter-test
51 | test
52 |
53 |
54 | org.springframework.boot
55 | spring-boot-configuration-processor
56 | true
57 |
58 |
59 |
60 |
61 |
62 |
63 | org.springframework.boot
64 | spring-boot-maven-plugin
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/samples/webapp-spring-boot-oauth2/README.md:
--------------------------------------------------------------------------------
1 | Log in with Omnissa Identity Manager
2 | =========================================
3 |
4 | This demo application shows the use of Spring Boot and its built-in OAuth2 capabilities to
5 | let a user authenticate with Omnissa Identity Manager™ and then use the access token to
6 | access Omnissa Identity Manager resources (like the user information).
7 |
8 | This application is based on the [Spring Demo application](https://spring.io/guides/tutorials/spring-boot-oauth2/#_social_login_github)
9 | and has been modified to integrate Omnissa Identity Manager as an authorization server.
10 |
11 | ## Building the project
12 |
13 | ### Prerequisites
14 |
15 | - You need a [Omnissa Identity Manager organization](http://www.air-watch.com/omnissa-identity-manager-free-trial), like https://dev.omnissaidentity.asia, where you have __admin__ access.
16 | - The project requires JDK 8
17 |
18 | ### Building from IDE
19 |
20 | * Clone this project.
21 | * Then import the root folder. You can run the main class `SocialApplication`.
22 |
23 | ### Building from the Command line
24 |
25 | You can run the app by using:
26 | `$ mvn spring-boot:run`
27 |
28 | or by building the jar file and running it with `mvn package` and `java -jar target/*.jar` (per the Spring Boot docs and other available documentation).
29 |
30 | ### Configure the Demo App
31 |
32 | * Create an OAuth2.0 client in the Omnissa Identity Manager admin console.
33 | Go to `Catalog` -> `Settings` -> `Remote App Access`. Click on `Create Client`.
34 | The _redirect URI_ must be set to `http://localhost:8080/login/omnissa`
35 |
36 | * Edit the file `./src/main/resources/application.yml` to set your own Omnissa Identity Manager organization URL in the defined endpoints,
37 | and the OAuth2 client id and client secret as they were defined in the previous step:
38 |
39 | ```yaml
40 | omnissa:
41 | client:
42 | accessTokenUri: /SAAS/auth/oauthtoken
43 | userAuthorizationUri: /SAAS/auth/oauth2/authorize
44 | clientId:
45 | clientSecret:
46 | resource:
47 | userInfoUri: /SAAS/jersey/manager/api/userinfo
48 | ```
49 |
50 | ### Test the application
51 |
52 | The web application will be available on `http://localhost:8080`. Click on "Login with WorkspaceONE" to start the OAuth2 flow.
53 | You can use the default values and log in to the demo Omnissa Identity Manager system using:
54 |
55 | * Username: `userN`, where N=1..10
56 | * Password: `omnissa`
57 |
58 | ### What is happening?
59 |
60 | Your web application is a client application that authenticates the users using Omnissa Identity Manager
61 | through the OAuth2 authorization code grant and obtains an access token that is used to fetch some more information
62 | about the user. In that case, Omnissa Identity Manager is the authorization and resource server and check the access token before returning
63 | the user's information.
64 |
--------------------------------------------------------------------------------
/samples/DynamicRegistrationAppAuthDemo-Android/app/src/main/java/net/openid/appauth/DeviceRegistrationPendingIntentStore.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 The AppAuth for Android Authors. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package net.openid.appauth;
16 |
17 | import android.app.PendingIntent;
18 | import android.support.annotation.VisibleForTesting;
19 | import android.support.customtabs.CustomTabsIntent;
20 |
21 | import java.util.HashMap;
22 | import java.util.Map;
23 |
24 | /**
25 | * Singleton to mimic PendingIntentStore to store our {@link net.openid.appauth.DeviceRegistrationRequest}
26 | *
27 | * Stores {@link android.app.PendingIntent} associated with each {@link DeviceRegistrationRequest} made via
28 | * {@link DeviceAuthorizationService#performDeviceRegistrationRequest(DeviceRegistrationRequest, PendingIntent, CustomTabsIntent)}.
29 | * The pending intents are read and sent by
30 | * the {@link RedirectUriRegistrationReceiverActivity} when the redirect Uri is received.
31 | */
32 | class DeviceRegistrationPendingIntentStore {
33 | private Map mRequests = new HashMap<>();
34 | private Map mPendingIntents = new HashMap<>();
35 |
36 | private static DeviceRegistrationPendingIntentStore sInstance;
37 |
38 | private DeviceRegistrationPendingIntentStore() {
39 | }
40 |
41 | public static synchronized DeviceRegistrationPendingIntentStore getInstance() {
42 | if (sInstance == null) {
43 | sInstance = new DeviceRegistrationPendingIntentStore();
44 | }
45 | return sInstance;
46 | }
47 |
48 | public void addPendingIntent(DeviceRegistrationRequest request, PendingIntent intent) {
49 | Logger.verbose("Adding pending intent for state %s", request.state);
50 | mRequests.put(request.state, request);
51 | mPendingIntents.put(request.state, intent);
52 | }
53 |
54 | public DeviceRegistrationRequest getOriginalRequest(String state) {
55 | Logger.verbose("Retrieving original request for state %s", state);
56 | return mRequests.remove(state);
57 | }
58 |
59 | public PendingIntent getPendingIntent(String state) {
60 | Logger.verbose("Retrieving pending intent for scheme %s", state);
61 | return mPendingIntents.remove(state);
62 | }
63 |
64 | @VisibleForTesting
65 | void clearAll() {
66 | mPendingIntents.clear();
67 | mRequests.clear();
68 | }
69 | }
70 |
71 |
72 |
--------------------------------------------------------------------------------
/samples/DynamicRegistrationAppAuthDemo-Android/README.md:
--------------------------------------------------------------------------------
1 | # Mobile SSO Sample Application For Android
2 |
3 | ## Overview
4 |
5 | This application is an Android native demo application to show you how to achieve mobile single sign-on using the [AppAuth library](https://github.com/openid/AppAuth-Android) with Omnissa Identity Manager as your Authorization Server.
6 | It is based on the [demo application](https://github.com/openid/AppAuth-Android) provided by the OpenID Foundation.
7 |
8 | Omnissa Identity Manager supports the OAuth2.0 Authorization Code Grant for mobile apps but requires each application instance to register a unique __Client ID__ and __Client Secret__ for additional security.
9 | This application shows how to set up mobile single sign-on using the AppAuth standard library.
10 |
11 | ## Building the project
12 |
13 | ### Prerequisites
14 |
15 | - You need a [Omnissa Identity Manager organization](http://www.air-watch.com/omnissa-identity-manager-free-trial), like https://dev.omnissaidentity.asia, where you have __admin__ access.
16 | - The project requires the Android SDK for API level 23 (Marshmallow) to build, though the produced binaries only require API level 16 (Jellybean) to be used.
17 |
18 | ### Building from Android Studio
19 |
20 | * Clone this project.
21 | * Then in AndroidStudio, use File -> New -> Import project. Select the root folder.
22 |
23 | ### Building from the Command line
24 |
25 | DynamicRegistrationAppAuthDemo for Android uses Gradle as its build system. In order to build the library and app binaries, run `./gradlew assemble`
26 | The demo app is output to _app/build/outputs/apk_. In order to run the tests and code analysis, run `./gradlew check`.
27 |
28 | ### Configure the Demo App
29 |
30 | You will need to edit the file `./app/src/main/res/values/idp_configs.xml` and edit the following values:
31 |
32 | * the organization URL: this is the full URL of your Omnissa Identity Manager organization:
33 |
34 | ```xml
35 |
36 | https://dev.omnissaidentity.asia
37 | ```
38 |
39 | * the application template and redirection URI: this is the template you defined in the Omnissa Identity Manager admin console under
40 | `Catalog` -> `Settings` -> `Remote App Access`. Click on `Templates` and then `Create Template`.
41 | The `omnissa_auth_redirect_scheme` and `omnissa_auth_redirect_uri` must match what you defined in the previous application template.
42 |
43 | ```xml
44 |
45 | Omnissa-AppAuth-Samples-Template
46 | com.omnissa.idm.samples.mobilesso
47 | com.omnissa.idm.samples.mobilesso://oauth2redirect
48 | ```
49 |
50 | ### Test the application
51 |
52 | You can use the default values and log in to the demo Omnissa Identity Manager system using:
53 |
54 | * Username: `userN`, where N=1..10
55 | * Password: `omnissa`
56 |
--------------------------------------------------------------------------------
/samples/webapp-spring-boot-oauth2/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.omnissa.idm.samples
7 | webapp-spring-boot-oauth2
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | webapp-spring-boot-oauth2
12 | Demo project for Spring Boot and Omnissa OAuth2
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 1.4.0.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | 1.8
24 |
25 |
26 |
27 |
28 | org.springframework.boot
29 | spring-boot-starter-actuator
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-security
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-starter-web
38 |
39 |
40 | org.springframework.security.oauth
41 | spring-security-oauth2
42 |
43 |
44 | org.webjars
45 | angularjs
46 | 1.4.3
47 |
48 |
49 | org.webjars
50 | jquery
51 | 2.1.1
52 |
53 |
54 | org.webjars
55 | bootstrap
56 | 3.2.0
57 |
58 |
59 | org.webjars
60 | webjars-locator
61 |
62 |
63 |
64 | org.springframework.boot
65 | spring-boot-starter-test
66 | test
67 |
68 |
69 | org.springframework.boot
70 | spring-boot-configuration-processor
71 | true
72 |
73 |
74 |
75 |
76 |
77 |
78 | org.springframework.boot
79 | spring-boot-maven-plugin
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/samples/webapp-spring-boot-saml2/src/test/java/com/omnissa/idm/samples/saml/core/SAMLUserDetailsServiceImplTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Vincenzo De Notaris
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.omnissa.idm.samples.saml.core;
18 |
19 | import com.omnissa.idm.samples.saml.CommonTestSupport;
20 | import org.junit.Test;
21 | import org.junit.runner.RunWith;
22 | import org.opensaml.saml2.core.NameID;
23 | import org.springframework.beans.factory.annotation.Autowired;
24 | import org.springframework.boot.test.context.SpringBootTest;
25 | import org.springframework.security.core.GrantedAuthority;
26 | import org.springframework.security.core.authority.SimpleGrantedAuthority;
27 | import org.springframework.security.core.userdetails.User;
28 | import org.springframework.security.saml.SAMLCredential;
29 | import org.springframework.test.context.junit4.SpringRunner;
30 |
31 | import java.util.ArrayList;
32 | import java.util.List;
33 |
34 | import static org.junit.Assert.assertEquals;
35 | import static org.junit.Assert.assertNotNull;
36 | import static org.junit.Assert.assertTrue;
37 | import static org.mockito.Mockito.mock;
38 | import static org.mockito.Mockito.when;
39 |
40 |
41 | @RunWith(SpringRunner.class)
42 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
43 | public class SAMLUserDetailsServiceImplTest extends CommonTestSupport {
44 |
45 | @Autowired
46 | private SAMLUserDetailsServiceImpl userDetailsService;
47 |
48 | @Test
49 | public void testLoadUserBySAML() {
50 | // given
51 | NameID mockNameID = mock(NameID.class);
52 | when(mockNameID.getValue()).thenReturn(USER_NAME);
53 |
54 | SAMLCredential credentialsMock = mock(SAMLCredential.class);
55 | when(credentialsMock.getNameID()).thenReturn(mockNameID);
56 |
57 | // when
58 | Object actual = userDetailsService.loadUserBySAML(credentialsMock);
59 |
60 | // / then
61 | assertNotNull(actual);
62 | assertTrue(actual instanceof User);
63 |
64 | User user = (User) actual;
65 | assertEquals(USER_NAME, user.getUsername());
66 | assertEquals(USER_PASSWORD, user.getPassword());
67 | assertTrue(user.isEnabled());
68 | assertTrue(user.isAccountNonExpired());
69 | assertTrue(user.isCredentialsNonExpired());
70 | assertTrue(user.isAccountNonLocked());
71 | assertEquals(1, user.getAuthorities().size());
72 |
73 | List authorities = new ArrayList<>(user.getAuthorities());
74 | Object authority = authorities.get(0);
75 |
76 | assertTrue(authority instanceof SimpleGrantedAuthority);
77 | assertEquals(USER_ROLE, ((SimpleGrantedAuthority) authority).getAuthority());
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/samples/DynamicRegistrationAppAuthDemo-Android/app/src/main/java/net/openid/appauth/RedirectUriRegistrationReceiverActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 The AppAuth for Android Authors. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package net.openid.appauth;
16 |
17 | import android.annotation.SuppressLint;
18 | import android.app.Activity;
19 | import android.app.PendingIntent;
20 | import android.content.Intent;
21 | import android.net.Uri;
22 | import android.os.Bundle;
23 | import android.support.annotation.VisibleForTesting;
24 |
25 | /**
26 | * Activity that receives the redirect Uri sent by the device registration endpoint. This activity gets launched
27 | * when the user approves the app for use and it starts the {@link PendingIntent} given in
28 | * {@link DeviceAuthorizationService#performDeviceRegistrationRequest}.
29 | *
30 | *
App developers using this code must to register this activity in the manifest
31 | * with one intent filter for each redirect URI they are intending to use.
32 | *