Message Boards
Integrating external Idp (auth server) with Liferay 7.2 using Oauth2.0
Integrating external Idp (auth server) with Liferay 7.2 using Oauth2.0
Expert Posts: 253 Join Date: 1/25/16 Recent PostsHi I am currenty having issues integrating my application using an external IDP (Ping). Below is my use case Oauth2 flow:
- The user requests a page on the portal URL.
- When click on the portal URL link the user get redirects to the Identity Provider login screen to prompt for userid and password
- The IDP authenticates the user via Oauth2 and kerbose
- The user is redirected back to the portal with an authorization code
- The portal application fetches the Authorization code by make a POST to called to recieve the Ouath2 JSON web token data from external IDP.
- Finally, the liferay portal appplication decode the token and uses the emailAddres to Autologin to authorize the user using liferay AutoLogin API.
The problem is I need to know how to get to my landing page as an Administrator or non admin user when the authentication is successful. The authenitcation was successful because the credetials were returned and i did not recieve null pointer exception. If I set AUTO_LOGIN_REDIRECT to a private page I get error message. Also, if I remove setting the attribute AUTO_LOGIN_REDIRECT I need to know if Autlogin will redirect to my default landing page configured in Admintration panel?
2020-10-27 14:13:24.398 ERROR [default task-3][AutoLoginFilter:258] Current URL /c/portal/login?code=unlk5SjM4kNVL0TymSRBx1r3TNbOu-gfXE1aZNpR generates exception: UT010019: Response already commited
Below is my code snippet:
@Component(
immediate = true,
service = AutoLogin.class
)
public class
AutoLoginService implements AutoLogin {
private
static final Log _log =
LogFactoryUtil.getLog(AutoLoginService.class);
@Override
public String[] handleException(HttpServletRequest
httpServletRequest, HttpServletResponse httpServletResponse,
Exception e) throws AutoLoginException {
// TODO
Auto-generated method stub
return null;
}
@Override
public String[] login(HttpServletRequest
httpServletRequest, HttpServletResponse httpServletResponse)
throws AutoLoginException {
User user =
null;
String email = null;
String authCode
= null;
long companyId = 0;
String[]
credentials = null;
try {
companyId =
PortalUtil.getCompanyId(httpServletRequest);
_log.info("COMPANY ID =["+companyId+"]");
//Call Authorization server using Oauth2 Auth
Endpoint
Response clientResponse =
ClientBuilder.newClient().target(OauthBaseUrl)
.path(OAuthAthorizationEndpoint)
.queryParam("client_id", "XXXX")
.queryParam("redirect_uri",
"http://localhost:8081/c/portal/login")
.queryParam("response_type",
"code")
.queryParam("grant_type",
"autorization_code")
.queryParam("scope", " ")
.queryParam("client_secret", "XXXXXX")
.request(MediaType.APPLICATION_JSON_TYPE)
.header("X-XSRF-Header",
"XXXXX")
.get();
//Get auth Server Login Screen - Redirect to authServer Login
Screen
if(clientResponse.getStatus() == 302)
{
httpServletResponse.sendRedirect("OauthBaseUrl&callbackURI=locahost:8081/c/portal/login");
//Get Auth Code - After login AUth server, extract the
Auth code from query param in URL from the response
authCode =
httpServletRequest.getParameter("code");
if (authCode != null) {
_log.info("CODE =["+authCode+"]");
//Fetch for token making a POST request using the
AuthCode
String token =
fetchOaAuth2Token(authCode);
String[] parts
= token.split("\\.");
JSONObject
payload = new JSONObject(decode(parts[1]));
_log.info(payload.getString("mail"));
email = payload.getString("mail");
}
}
//After success token request
login to liferay using the credentials emailAddress,userId and
password
if(Validator.isNotNull(email)) {
user = _userLocalService.getUserByEmailAddress(companyId,
email);
String url =
"http://localhost:8081/web/guest/documenturl";
//String path = PrefsPropsUtil.getString(companyId,
PropsKeys.DEFAULT_LANDING_PAGE_PATH);
httpServletRequest.setAttribute(AUTO_LOGIN_REDIRECT,path);
credentials = new String[] {
String.valueOf(user.getUserId()),
user.getPassword(),
String.valueOf(user.isPasswordEncrypted()) };
}
return
credentials;
} catch (PortalException
e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception ex) {
_log.info("no user found");
ex.printStackTrace();
return null;
}
//return new String[]{email, user.getPassword() ,
Boolean.TRUE.toString()};
return null;
}
@Reference
public void
setUserLocalService(UserLocalService userLocalService) {
this._userLocalService = userLocalService;
}
@Reference
private UserLocalService _userLocalService;
RE: Integrating external Idp (auth server) with Liferay 7.2 using Oauth2.0
Expert Posts: 253 Join Date: 1/25/16 Recent PostsI Finally figured out the problem. Couple of changes need to do
- I had to setup my landing page in the Administration Control /web/guest/login
-
I had to create two component classes:
- a filter component that subclass the BaseFilter class to override the prcessFilter() method
- Inside my Filter Component my @Activate when startup should call AUth Server
- a autologin componnet that subclass the BaseAutologin
- Inside my Filter Component my @Activate when startup should log user into liferay after getttin user details from the token claims
- After implementing and activating those two components that work in tandem i was able login to Liferay user the user info in claims by decoding the token from Authorization server
Code Sniipet:
@Component(
immediate = true,
property = {
"dispatcher=FORWARD",
"dispatcher=REQUEST",
"servlet-context-name=",
"servlet-filter-name=SSO Oauth2.0 Filter",
"url-pattern=/c/portal/login",
"url-pattern=/c/portal/logout"
},
service
= Filter.class
)
/** Filter Component
*/
public
class SSOFilter extends BaseFilter {
private
static final Log LOG =
LogFactoryUtil.getLog(AuthenticationSSOFilter.class);
private FilterAdapter filterAdapter;
@Activate
@Modified
protected void
activate() {
LOG.info("****************
SSOFilter Activated ******************");
filterAdapter = new FilterAdapter(new
PortalAdapterImpl(_userLocalService));
}
@Override
protected void processFilter(
HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain)
throws
Exception {
override this methhod by calling processFilter()
}
}
/**
*
*/
@Component(
immediate =
true,
service = AutoLogin.class
)
public
class AutoLoginService extends BaseAutoLogin {
@Activate
protected void activate() {
_log.info("**************** AutoLoginService Activated
******************");
autoLoginAdapter = new
AutoLoginAdapter(new PortalAdapterImpl(_userLocalService));
}
@Override
protected String[] doLogin(HttpServletRequest
request, HttpServletResponse response) throws Exception {
return autoLoginAdapter.doLogin(request, response);
}
}