OAuth 2.0 (A & A)

Kiran Chowdhary
19 min readMay 28, 2018

--

Open Standard Authentication

OAuth is an open standard for access delegation, commonly used as a way for Internet users to grant websites or applications access to their information on other websites but without giving them the passwords.

Generally, OAuth provides to clients a “secure delegated access” to server resources on behalf of a resource owner.

It specifies a process for resource owners to authorize third-party access to their server resources without sharing their credentials.

Designed specifically to work with Hypertext Transfer Protocol (HTTP), OAuth essentially allows access tokens to be issued to third-party clients by an authorization server, with the approval of the resource owner. The third party then uses the access token to access the protected resources hosted by the resource server.

Contents

  1. History
  2. OAuth 2.0
  3. Security terms with reference to legacy JEE systems.
  4. Traditional JEE Application Server Anatomy.
  5. Drawbacks of traditional system.
  6. OAuth in Action…
  7. References

History

OAuth began in November 2006 when Blaine Cook was developing the Twitter OpenID implementation. Meanwhile, Ma. needed a solution to allow its members with OpenIDs to authorize Dashboard Widgets to access their service. Cook, Chris Messina and Larry Halff from Magnolia met with David Recordon to discuss using OpenID with the Twitter and Ma.gnolia APIs to delegate authentication. They concluded that there were no open standards for APIaccess delegation.

The OAuth discussion group was created in April 2007, for the small group of implementers to write the draft proposal for an open protocol. DeWitt Clinton from Google learned of the OAuth project, and expressed his interest in supporting the effort. In July 2007, the team drafted an initial specification. Eran Hammer joined and coordinated the many OAuth contributions creating a more formal specification. On December 4, 2007, the OAuth Core 1.0 final draft was released.[4]

At the 73rd Internet Engineering Task Force (IETF) meeting in Minneapolis in November 2008, an OAuth BoF was held to discuss bringing the protocol into the IETF for further standardization work. The event was well attended and there was wide support for formally chartering an OAuth working group within the IETF.

The OAuth 1.0 protocol was published as RFC 5849, an informational Request for Comments, in April 2010.

Since August 31, 2010, all third party Twitter applications have been required to use OAuth.

The OAuth 2.0 framework was published as RFC 6749, and the Bearer Token Usage as RFC 6750, both standards track Requests for Comments, in October 2012.

OAuth 2.0

OAuth 2.0 is not backwards compatible with OAuth 1.0. OAuth 2.0 provides specific authorization flows for web applications, desktop applications, mobile phones, and living room devices. The specification and associated RFCs are developed by the IETF OAuth WG;[6] the main framework was published in October 2012.

Facebook’s Graph API only supports OAuth 2.0.[7] Google supports OAuth 2.0 as the recommended authorization mechanism for all of its APIs.[8] Microsoft[9] also supports OAuth 2.0 for various APIs and its Azure Active Directory service, which is used to secure many Microsoft and third party APIs.

The OAuth 2.0 Framework[10] and Bearer Token Usage[11] were published in October 2012.

Security terms with reference to legacy JEE systems

  • Web server : A Web server is a program (or a daemon process) that uses HTTP (Hypertext Transfer Protocol) to serve the files that form Web pages to users, in response to their requests. Ex. Apache, Tomcat, Glassfish etc..
  • HTTP listener : Each virtual server provides connections between the server and clients through one or more HTTP listeners. Each HTTP listener is a listen socket that has an IP address, a port number, a server name, and a default virtual server.
  • Public URI’s vs protected URI’s : Public URI’s are generally accessible by public Ex. A web site data (https://www.google.com) . Access to protected URI’s are limited to certain users, certain roles or for certain users groups. Ex. your social account information (https://mail.google.com).
  • Authentication : Authentication is a process that ensures and confirms a user’s identity. Authentication is one of the five pillars of information assurance (IA). The other four are integrity, availability, confidentiality and nonrepudiation.
  • Authorization : Authorization is a security mechanism used to determine user/client privileges or access levels related to system resources, including computer programs, files, services, data and application features.
  • Realms, Users, Groups, and Roles : A realm is a security policy domain defined for a web or application server. A realm contains a collection of users, who may or may not be assigned to a group. A user is an individual or application program identity that has been defined in the server. A group is a set of authenticated users, classified by common traits, defined in the Server. A role is an abstract name for the permission to access a particular set of resources in an application
  • Security filter : Security filters enable you to control what data (or what urls) users can access when that data is accessed through MicroStrategy. Ex. Apache Shiro security filter.

Web.xml

<filter> 
<filter-name>ShiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>ShiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Shiro.ini

[main]# password matcher#passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher#passwordService = org.apache.shiro.authc.credential.DefaultPasswordService#passwordMatcher.passwordService = $passwordServicesha256Matcher = org.apache.shiro.authc.credential.HashedCredentialsMatchersha256Matcher.hashAlgorithmName = SHA-256sha256Matcher.hashIterations=1# base64 encodingsha256Matcher.storedCredentialsHexEncoded = false#matcher = org.apache.shiro.authc.credential.SimpleCredentialsMatcher#datasource typeds = org.apache.shiro.jndi.JndiObjectFactory#datasourcenameds.resourceName = jdbc/testresource#datasourcetypeds.requiredType = javax.sql.DataSource#fbCredentialsMatcher = com.connectifier.authc.facabook.FaceBookCreadentialsMatcher#FaceBookRealm = com.connectifier.authc.realm.FaceBookRealm#FaceBookRealm.credentialsMatcher = $fbCredentialsMatcher#configuring jdbc realmjdbcRealm = com.connectifier.authc.realm.CustomJDBCRealm#jdbcRealm.credentialsMatcher = $matcherjdbcRealm.credentialsMatcher = $sha256MatcherjdbcRealm.dataSource=$dsjdbcRealm.userRolesQuery=select name from role where email = ? and isactive=1jdbcRealm.authenticationQuery=select hash, salt from user where email = ? and isactive=1jdbcRealm.permissionsLookupEnabled=false#securityManager.realms = $jdbcRealm,$FaceBookRealmsecurityManager.realms = $jdbcRealm#login urlauthc.loginUrl = /#page to redirected to after logoutlogout.redirectUrl = /#page to where to land after loginauthc.successUrl = /#username parameter name in the loginformauthc.usernameParam = username#password parameter name in the loginformauthc.passwordParam = password#rememberme parameter name in the loginformauthc.rememberMeParam=rememberme#cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager#securityManager.cacheManager = $cacheManager#jdbcRealm.authenticationCachingEnabled = true[urls]# The /login.jsp is not restricted to authenticated users (otherwise no one could log in!), but# the 'authc' filter must still be specified for it so it can process that url's# login submissions. It is 'smart' enough to allow those requests through as specified by the# shiro.loginUrl above./logout = logout/index.jsp = anon/login = anon/action = anon/* = authc

CustomJDBCRealm.java

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.util.JdbcUtils;
import org.apache.shiro.util.SimpleByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author kkumar1
*
* Application specific JDBC realm. If required override methods of {@link JdbcRealm} to load users, roles and
* permissions from database.
*
* Do not override configuration in code if it can be done via shiro.ini file.
*/
public class CustomJDBCRealm extends JdbcRealm {
private static final Logger log = LoggerFactory.getLogger(JdbcRealm.class);public CustomJDBCRealm() {
super();
setSaltStyle(SaltStyle.COLUMN);
}
/**
* overriding the method which is in JdbcRealm. If SaltStyle is COLUMN, then gets String salt value from database
* and forms salt byte array of type {@link ByteSource} with decoded string salt value and sets it to salt value of
* AuthenticationInfo.
*/
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String username = upToken.getUsername();
// Null username is invalid
if (username == null) {
throw new AccountException("Null usernames are not allowed by this realm.");
}
Connection conn = null;
SimpleAuthenticationInfo info = null;
try {
conn = dataSource.getConnection();
String password = null;
String salt = null;
switch (saltStyle) {
case NO_SALT:
case CRYPT:
case EXTERNAL:
return super.doGetAuthenticationInfo(token);
case COLUMN:
String[] queryResults = getPasswordForUser(conn, username);
password = queryResults[0];
salt = queryResults[1];
break;
}
if (password == null) {
throw new UnknownAccountException("No account found for user [" + username + "]");
}
info = new SimpleAuthenticationInfo(username, password.toCharArray(), getName());if (salt != null) {
info.setCredentialsSalt(new SimpleByteSource(Base64.decode(salt)));
}
} catch (SQLException e) {
final String message = "There was a SQL error while authenticating user [" + username + "]";
if (log.isErrorEnabled()) {
log.error(message, e);
}
throw new AuthenticationException(message, e);
} finally {
JdbcUtils.closeConnection(conn);
}
return info;
}
private String[] getPasswordForUser(Connection conn, String username) throws SQLException {String[] result;
boolean returningSeparatedSalt = false;
switch (saltStyle) {
case NO_SALT:
case CRYPT:
case EXTERNAL:
result = new String[1];
break;
default:
result = new String[2];
returningSeparatedSalt = true;
}
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(authenticationQuery);
ps.setString(1, username);
rs = ps.executeQuery();
boolean foundResult = false;
while (rs.next()) {
if (foundResult) {
throw new AuthenticationException("More than one
user row found for user [" + username
+ "]. Usernames must be unique.");
}
result[0] = rs.getString(1);
if (returningSeparatedSalt) {
result[1] = rs.getString(2);
}
foundResult = true;
}
} finally {
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(ps);
}
return result;
}
}
  • Session (Http session): Session is a conversional state between client and server and it can consists of multiple request and response between client and server. Session Ids are unique, transient and non-guessable numbers / string. Ex. sessionId = SHA2(userId + ipAddr) + prngRandomNumber.
/* JSP example of a session */
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<%
session.getId();
session.getMaxInactiveInterval();session.getLastAccessedTime();session.invalidate();%>/*Authentication tags*/<shiro:guest>
/* guest user, -- show him login page.*/
</shiro:guest>
<shiro:user>
/*Authenticated user, show him dashboard. */
</shiro:user>/*Permisssion tags*/<shiro:hasPermission name="users:manage">
<a href="manageUsers.jsp">Click here to manage users</a> </shiro:hasPermission>
<shiro:lacksPermission name="users:manage">
No user management for you!
</shiro:lacksPermission>

Annotations for access control

@RequiresRoles("administrator") 
public void deleteUser(User user) {
//this method will only be invoked by an administrator ...
}
@RequiresGuest
public void signUp(User newUser) {
//this method will only be invoked by a Subject that is unknown/anonymous ...
}

Accessing session in servlet

/* Accessing session in servlet */public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {

req.getSession();
}

Take look at the source code of simple session here https://github.com/apache/shiro/blob/2.0-api-design-changes/core/src/main/java/org/apache/shiro/session/mgt/SimpleSession.java

  • Cookies (HTTP cookies): An HTTP cookie (web cookie, browser cookie) is a small piece of data that a server sends to the web browser. The browser may store it and send it back with the next request to the same server. Typically, it’s used to tell if two requests came from the same browser — keeping a user logged-in, for example. It remembers stateful information for the stateless HTTP protocol.

How Session is managed? Know the cookie?

When a client visits the web-app for the first time and/or the HttpSession is to be obtained for the first time by request.getSession(), then the servlet container will create it, generate a long and unique ID (which you can get by session.getId()) and store it in server’s memory. The servlet container will also set a Cookie in the HTTP response with JSESSIONID as cookie name and the unique session ID as cookie value.

As per the HTTP cookie specification (a contract a decent web browser and web server has to adhere), the client (the web browser) is required to send this cookie back in the subsequent requests as long as the cookie is valid. The servlet container will determine every incoming HTTP request header for the presence of the cookie with the name JSESSIONID and use its value to get the associated HttpSession from server’s memory.

The HttpSession lives until it has not been used for more than the time, a setting you can specify in web.xml, which defaults to 30 minutes. So when the client doesn’t visit the web application anymore for over 30 minutes, then the servlet container will trash the session. Every subsequent request, even though with the cookie specified, will not have access to the same session anymore. The servlet container will create a new one.

For more information on session management, take a look at the source code https://github.com/apache/shiro/blob/master/web/src/main/java/org/apache/shiro/web/session/mgt/ServletContainerSessionManager.java

  • Domains, DNS and Virtual hosting : Domain names are used to identify one or more IP addresses, DNS is Internet’s system for converting alphabetic domain names into numeric IP addresses. Virtual hosting is a method for hosting multiple domain names (with separate handling of each name) on a single server (or pool of servers). This allows one server to share its resources, such as memory and processor cycles, without requiring all services provided to use the same host name.
  • Principal : The term principal is just a fancy security term for any identifying attribute(s) of an application user, such as a username, or user id, or public key, or anything else you might use in your application to identify a user.
  • Subject (or Web Subject) : To authorize access to resources, applications first need to authenticate the source of the request. The JAAS framework defines the term subject to represent the source of a request. A subject may be any entity, such as a person or service. A subject is represented by the javax.security.auth.Subjectclass. Web subject will be bound to a thread which executes the request using thread locals.
/* JSP example of a Shiro SecurityUtils */
<%
SecurityUtils.getSubject();
%>

Subject interface source code example.

public interface Subject {
Object getPrincipal();
PrincipalCollection getPrincipals();
boolean isPermitted(String permission);
boolean isPermitted(Permission permission);
boolean[] isPermitted(String… permissions);
boolean[] isPermitted(List<Permission> permissions);
boolean isPermittedAll(String… permissions);
boolean isPermittedAll(Collection<Permission> permissions);
void checkPermission(String permission) throws AuthorizationException; void checkPermission(Permission permission) throws AuthorizationException; void checkPermissions(String… permissions) throws AuthorizationException; void checkPermissions(Collection<Permission> permissions) throws AuthorizationException; boolean hasRole(String roleIdentifier);
boolean[] hasRoles(List<String> roleIdentifiers);
boolean hasAllRoles(Collection<String> roleIdentifiers);
void checkRole(String roleIdentifier) throws AuthorizationException;
void checkRoles(Collection<String> roleIdentifiers) throws AuthorizationException; void checkRoles(String… roleIdentifiers) throws AuthorizationException; void login(AuthenticationToken token) throws AuthenticationException; boolean isAuthenticated();
boolean isRemembered();
Session getSession();
Session getSession(boolean create);
void logout();
<V> V execute(Callable<V> callable) throws ExecutionException;
void execute(Runnable runnable);
<V> Callable<V> associateWith(Callable<V> callable);
Runnable associateWith(Runnable runnable);
void runAs(PrincipalCollection principals) throws NullPointerException, IllegalStateException;
boolean isRunAs();
PrincipalCollection getPreviousPrincipals();
PrincipalCollection releaseRunAs();
}

Implementation of WebSubject interface.

WebSubject binding to current thread

Example of ThreadLocals

Java provides an ThreadLocal object using which you can set/get thread scoped variables. Below is a code example demonstrating what I’d explained above.

UML diagram of Thread, ThreadLocal and ThreadLocalMap

Lets first have the Context.java file which will hold the transactionId field.

package com.globalauth;  public class Context {   
private StringtransactionId = null;
/* getters and setters here */
}

Now create the MyThreadLocal.java file which will act as a container to hold our context object.

package com.globalauth;/**  * this class acts as a container to our thread local variables.  * @author kkumar1  *  */ 
public class MyThreadLocal {
public static final ThreadLocal userThreadLocal = new ThreadLocal();
public static void set(Context user) {
userThreadLocal.set(user);
}
public static void unset() {
userThreadLocal.remove();
}
public static Context get() {
return userThreadLocal.get();
}
}

In the above code, you are creating a ThreadLocal object as a static field which can be used by rest of the code to set/get thread local variables.

Let’s create our main class file which will generate and set the transaction ID in thread local and then call the business method.

package com.globalauth;public class ThreadLocalDemo extends Thread {   
public static void main(String args[]) {
Thread threadOne = new ThreadLocalDemo();
threadOne.start();
Thread threadTwo = new ThreadLocalDemo();
threadTwo.start();
}
@Override
public void run() { // sample code to simulate transaction id
Context context = new Context();
context.setTransactionId(getName()); // set the context object in thread local to access it somewhere else
MyThreadLocal.set(context); /* note that we are not explicitly passing the transaction id */
new BusinessService().businessMethod();
MyThreadLocal.unset();
}
}

Finally, here’s the code for the BusinessService.java which will read from thread local and use the value.

package com.globalauth;public class BusinessService {   
public void businessMethod() { // get the context from thread local
Context context = MyThreadLocal.get();
System.out.println(context.getTransactionId());
}
}

When you run the ThreadLocalDemo file, you’ll get the below output:

Thread-0 
Thread-1
  • Resource owner : An entity capable of granting access to a protected resource. When the resource owner is a person, it is referred to as an
    end-user.
  • Resource server : The server hosting the protected resources, capable of accepting and responding to protected resource requests using access tokens.
  • Application/client : An application making protected resource requests on behalf of the resource owner and with its authorization. The term “client” does not imply any particular implementation characteristics (e.g.,
    whether the application executes on a server, a desktop, or other
    devices).
  • Authorization server : The server issuing access tokens to the client after successfully authenticating the resource owner and obtaining authorization.
  • Access token : Access token is what is issued to the client once the client successfully authenticates itself (using the consumer key & secret). This access token defines the privileges of the client (what data the client can and cannot access). Now every time the client wants to access the end-user’s data, the access token secret is sent with the access token as a password.
  • Refresh token : A Refresh Token is a special kind of token that can be used to obtain a renewed access token — that allows accessing a protected resource — at any time.

Traditional JEE Application Server Anatomy

Traditional JEE application server
  1. Web browser : A web browser (commonly referred to as a browser) is a software application for accessing information on the World Wide Web. Which acts as a mediator between web server and user.
  2. HTTP listener : Is a daemon process listening on specific port for HTTP requests. On receiving a request it will create new thread and delegates the request to request handler (or request processor).
  3. Filter chains : It is a bunch of filters organized in specific order, where each of the filters has a particular responsibility and filters are added or removed from the configuration depending on which services are required.The ordering of the filters is important as there are dependencies between them.
  4. Application: Your JEE application containing servlets, MVC controllers or REST controllers, based on the request URI, the request dispatcher or servlet mapper dispatcher routes request to appropriate controller using information defined in deployment descriptor.
  5. Deployment descriptor & application context : Deployment descriptor is a configuration file for an artifact that is deployed to some container/engine. It describes how a component, module or application should be deployed. It directs a deployment tool to deploy a module or application with specific container options, security settings and describes specific configuration requirements. XML is used for the syntax of these deployment descriptor files. For web applications, the deployment descriptor must be called web.xml and must reside in the WEB-INF directory in the web application root. For Java EE applications, the deployment descriptor must be named application.xml and must be placed directly in the META-INF directory at the top level of the application.ear file. The ApplicationContext is the central interface within a Spring Application for providing configuration information to the application. It is read-only at run time , but can be reloaded if necessary and supported by the application.
  6. Request processor : On receiving a request, it validates the request and binds correct session to the current thread.

Request processor is an abstract term, It consists of several modules or micro modules depending on the vendor. The below are few of them.

Location Manager–The location manager parses the incoming IP address, as well as IP addresses present in alternate tracking headers, such as the X-Forwarded-For header.

Environment Manager–The environment manager parses the incoming user-agent header, if present.

Drawbacks of traditional system.

In the traditional client-server authentication model, the client
requests an access-restricted resource (protected resource) on the
server by authenticating with the server using the resource owner’s
credentials. In order to provide third-party applications access to
restricted resources, the resource owner shares its credentials with
the third party. This creates several problems and limitations:

  • Third-party applications are required to store the resource
    owner’s credentials
    for future use, typically a password in
    clear-text.
  • Servers are required to support password authentication, despite
    the security weaknesses inherent in passwords.
  • Third-party applications gain overly broad access to the resource
    owner’s protected resources, leaving resource owners without any
    ability to restrict duration or access to a limited subset of
    resources
    .
  • Resource owners cannot revoke access to an individual third party
    without revoking access to all third parties, and must do so by
    changing the third party’s password.
  • Compromise of any third-party application results in compromise of
    the end-user’s password and all of the data protected by that
    password.

OAuth in Action…

OAuth addresses these issues by introducing an authorization layer
and separating the role of the client from that of the resource
owner
. In OAuth, the client requests access to resources controlled
by the resource owner and hosted by the resource server, and is
issued a different set of credentials than those of the resource
owner.

Instead of using the resource owner’s credentials to access protected
resources, the client obtains an access token — a string denoting a
specific scope, lifetime, and other access attributes. Access tokens
are issued to third-party clients by an authorization server with the
approval of the resource owner. The client uses the access token to
access the protected resources hosted by the resource server.

Authorization grant : An authorization grant is a credential representing the resource owner’s authorization (to access its protected resources) used by the client to obtain an access token. This specification defines four
grant types — authorization code, implicit, resource owner password
credentials, and client credentials
— as well as an extensibility
mechanism for defining additional types.

  • Authorization code : The authorization code is obtained by using an authorization server as an intermediary between the client and resource owner. Instead of requesting authorization directly from the resource owner, the client directs the resource owner to an authorization server, which in turn directs the resource owner back to the client with the authorization code.

Before directing the resource owner back to the client with the authorization code, the authorization server authenticates the resource owner and obtains authorization. Because the resource owner only authenticates with the authorization server, the resource owner's credentials are never shared with the client.

The authorization code provides a few important security benefits, such as the ability to authenticate the client, as well as the transmission of the access token directly to the client without passing it through the resource owner's user-agent and potentially exposing it to others, including the resource owner.

  • Implicit : The implicit grant is a simplified authorization code flow optimized for clients implemented in a browser using a scripting language such as JavaScript. In the implicit flow, instead of issuing the client an authorization code, the client is issued an access token directly. The grant type is implicit, as no intermediate credentials are issued.

When issuing an access token during the implicit grant flow, the authorization server does not authenticate the client. In some cases, the client identity can be verified via the redirection URI used to deliver the access token to the client. The access token may be exposed to the resource owner or other applications with access to the resource owner's user-agent.

Implicit grants improve the responsiveness and efficiency of some clients, since it reduces the number of round trips required to obtain an access token. However, this convenience should be weighed against the security implications of using implicit grants, such as those described in Sections 10.3 and 10.16, especially when the authorization code grant type is available.

  • Resource owner password credentials : The resource owner password credentials can be used directly as an authorization grant to obtain an access token. The credentials should only be used when there is a high degree of trust between the resource owner and the client (e.g., the client is part of the device operating system or a highly privileged application), and when other authorization grant types are not available (such as an authorization code).

Even though this grant type requires direct client access to the
resource owner credentials, the resource owner credentials are used
for a single request and are exchanged for an access token. This
grant type can eliminate the need for the client to store the
resource owner credentials for future use, by exchanging the
credentials with a long-lived access token or refresh token.

  • Client credentials : The client credentials (or other forms of client authentication) can be used as an authorization grant when the authorization scope is limited to the protected resources under the control of the client, or to protected resources previously arranged with the authorization server. Client credentials are used as an authorization grant typically when the client is acting on its own behalf (the client is also the resource owner) or is requesting access to protected resources based on an authorization previously arranged with the authorization server.

Interoperability

OAuth 2.0 provides a rich authorization framework with well-defined security properties. However, as a rich and highly extensible framework with many optional components, on its own, this specification is likely to produce a wide range of non-interoperable implementations.

In addition, this specification leaves a few required components partially or fully undefined (e.g., client registration, authorization server capabilities, endpoint discovery). Without these components, clients must be manually and specifically configured against a specific authorization server and resource server in order to interoperate.

Client Types

Public : Clients incapable of maintaining the confidentiality of their
credentials (e.g., clients executing on the device used by the
resource owner, such as an installed native application or a web
browser-based application), and incapable of secure client
authentication via any other means.

Confidential : Clients capable of maintaining the confidentiality of their
credentials (e.g., client implemented on a secure server with
restricted access to the client credentials), or capable of secure
client authentication using other means.

Client Registration

Before initiating the protocol, the client registers with the authorization server. The means through which the client registers with the authorization server are beyond the scope of this specification but typically involve end-user interaction with an HTML registration form.
Client registration does not require a direct interaction between the client and the authorization server. When supported by the authorization server, registration can rely on other means for establishing trust and obtaining the required client properties (e.g., redirection URI, client type). For example, registration can be accomplished using a self-issued or third-party-issued assertion, or by the authorization server performing client discovery using a trusted channel.

Appendix

Validating access token : Validating access token by resource server is beyond the scope of this article and is specific to the vendor/implementor . However, the open standard implementation to validate the access token is JWT(JSON Web Token).

Learn more, Know more

Re-using Web subject and stacking previous principals : Since the user permissions, user roles and user groups will not change often, Hence shiro will retain the subject in cache and binds the new principal to the cached Web subject.

--

--