<file_sep># nemo
* nemo and nemo2 are identical applications running on different ports
* both use spring session + redis so you must have redis running locally; they need nemo-account for authentication
* $ redis-server /usr/local/etc/redis.conf
* nemo-account is the authentication server using oauth2; see user credential in application.yml
* nemo-resource is resource (REST end points) server; it needs nemo-account for authentication
* see application.yml in each app for configuration settings including server port
* In Eclipse, make sure you do Maven -> Update Project after getting the code
* If you'd like to disable Redis, comment out @EnableRedisHttpSession in nemo or nemo2 projects, and remove redis maven dependency in projects's pom.xml.

Two ideas explored in this Poc
* Load balance between nemo and nemo2. Spring session + redis should allow you to shudown one application and update it withou user loosing session
* OAuth2 provides single sign-on as well as API consumption using bearer token
<file_sep>package com.nemo.resource;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
@EnableResourceServer
public class NemoResourceApplication {

    @RequestMapping("/api/version")
    public Map<String,Object> home() {
      Map<String,Object> model = new HashMap<String,Object>();
      model.put("version", "v0.1");
      model.put("time", new SimpleDateFormat().format(new Date()));
      model.put("message", "Hello, this data comes from resource server");
      return model;
    }

	public static void main(String[] args) {
		SpringApplication.run(NemoResourceApplication.class, args);
	}
}
<file_sep>package com.nemo.accounts;

import java.security.Principal;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@SpringBootApplication
@RestController
@EnableResourceServer // by default secures everything in an authorization server except the "/oauth/*" endpoints
public class NemoAccountsApplication {
    @RequestMapping({"/user", "/me"})
    public Principal user(Principal user) {
        return user;
    }

    @Configuration
    @Order(-20)
    protected static class LoginConfig extends WebSecurityConfigurerAdapter {

        @Autowired
        private AuthenticationManager authenticationManager;

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            http
                .formLogin()
                  .loginPage("/login")
                  .permitAll()
                .and()
                  .requestMatchers()
                  .antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
                .and()
                    .authorizeRequests()
                      .anyRequest()
                      .authenticated();
            // @formatter:on
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.parentAuthenticationManager(authenticationManager);
        }
    }

    @Configuration
    @EnableAuthorizationServer
    protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {

         @Autowired
         private AuthenticationManager authenticationManager;

         @Override
         public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
              endpoints.authenticationManager(authenticationManager);
         }

         @Override
         public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
              // @formatter:off
              clients.inMemory()
              .withClient("acme")
              .authorizedGrantTypes("authorization_code","refresh_token","password", "client_credentials")
              .scopes("nemo")
              .secret("acmesecret")
              .autoApprove("nemo")
              .and()
              .withClient("cmp")
              .authorizedGrantTypes("authorization_code","refresh_token","password")
              .scopes("cmp")
              .secret("cmpsecret")
              .autoApprove("cmp")
              // .redirectUris("http://platform.ias.dev.com:8080/cmp")
              .and()
              .withClient("client-with-registered-redirect")
              .authorizedGrantTypes("authorization_code")
              .authorities("ROLE_CLIENT")
              .scopes("read", "trust")
              .resourceIds("api_v1")
              .redirectUris("http://anywhere?key=value")
              .secret("secret123")
              .and()
              .withClient("my-client-with-secret")
              .authorizedGrantTypes("client_credentials", "password")
              .authorities("ROLE_CLIENT")
              .scopes("read")
              .resourceIds("api_v2")
              .secret("secret");
              // @formatter:on
         }

    }

    public static void main(String[] args) {
		SpringApplication.run(NemoAccountsApplication.class, args);
	}
}
