SSO Integration Guide (Using AIV Library)
This guide walks you through how to integrate SSO (Single Sign-On) in a Spring Boot / Java project using the AIV-provided libraries.
-
Create the Project
We recommend creating a Spring Boot project. You can also use a standard Java project if needed.
-
Add Required JARs
Include the following JARs (to be provided by AIV):
- aiv-security.jar
- aiv-common.jar
These contain interfaces and utility classes necessary for authentication and security.
-
Implement IAuthentication Interface
Create a class that implements IAuthentication (from the provided JAR).
public class CustomAuthImpl implements IAuthentication { @Override public boolean isAuthorize(Map<String, Object> headers) { // Your logic here return true; } @Override public Map<String, String> authentication(Map<String, Object> userdetails) { // Your logic to authenticate and return user details return userDetails; } // Other required methods... }
-
Create a Filter to Intercept Requests
Write a filter to intercept requests that require authentication.
@WebFilter("/*") @Order(Ordered.LOWEST_PRECEDENCE) public class FirstFilter implements Filter { Properties p = null; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; String userAgent = req.getHeader("user-agent"); String owner = req.getHeader("owner") != null ? req.getHeader("owner") : req.getHeader("userName") != null ? req.getHeader("userName") : null; String traceid = req.getHeader("traceid") != null ? req.getHeader("traceid") : req.getHeader("traceid") != null ? req.getHeader("traceid") : "SPRING AUTH"; String uri = req.getRequestURI(); Enumeration<String> params = req.getParameterNames(); while (params.hasMoreElements()) { String name = params.nextElement(); List<String> a = Arrays.asList(req.getParameterValues(name)); boolean fg = a.stream().anyMatch(j -> { return j.contains("\r") || j.contains("\n"); }); if (fg) { throw new IOException(); } } String ssotoken = req.getAttribute("sso") == null ? null : req.getAttribute("sso").toString(); if (uri.contains("/v3/") || uri.endsWith("html") || uri.endsWith("css") || uri.endsWith("js") || uri.endsWith("png") || uri.endsWith("add_intl") || uri.endsWith("get_intl") || (uri.endsWith("file_upload_servlet") && req.getHeader("isLicenseUpload") != null && "true".equalsIgnoreCase(req.getHeader("isLicenseUpload"))) || uri.contains("licenserequest") || uri.endsWith("papermill_upload") || uri.endsWith("/external/update_user_role") || uri.endsWith("/api/user/validate") || uri.endsWith("swf") || uri.endsWith("woff") || uri.endsWith(".woff2") || uri.endsWith(".map") || uri.endsWith("jpg") || uri.endsWith("svg") || uri.endsWith(".json") || uri.endsWith("ttf") || uri.endsWith("TermsandConditions.pdf") || uri.endsWith("/dept_list") || uri.endsWith("/iconFile.json") || uri.endsWith("/license_info") || uri.endsWith("/endpoint/executed") || uri.endsWith("/aivverion") || uri.endsWith("/aiv/logout") || uri.contains("/allow/callback")) { chain.doFilter(request, response); return; } List<String> addInfo = new ArrayList<String>(); addInfo.add(req.getHeader("User-Agent")); if (req.getMethod().equalsIgnoreCase("POST") && uri.endsWith("/authenticate")) { String str = IOUtils.toString(request.getInputStream(),StandardCharsets.UTF_8); String userName = null,pass = null,deptCode = null; traceid = UUID.randomUUID().toString(); if(str !=null && str.length()>0) { JSONObject jsonObj = new JSONObject(str); if(jsonObj!=null){ userName = jsonObj.getString("userName"); String[] _su = userName.contains("::") ? userName.split("::") : userName.split("/"); pass = jsonObj.getString("password"); System.out.println(pass); deptCode = jsonObj.getString("deptCode"); if(jsonObj.has("embed") && jsonObj.get("embed").equals(true)) { try { pass = new PaaswordCryptography().decryptEmbedPass(pass); } catch (Exception e) { // TODO Auto-generated catch block AuditLoggerUtil.log(AuditLoggerUtil.SECURITYLOGGER, AuditLoggerUtil.ERROR, FirstFilter.class, e.getMessage(),"AUTH","AUTH", e); } } if(_su.length>1) { deptCode=_su[0]; userName=_su[1]; } } } String responseData = null; Map<String, Object> user = new HashMap<>(); if(userName !=null){ SimpleAuthImpl i = new SimpleAuthImpl(); Map<String, Object> d = new HashMap<>(); user.put("userName",userName); user.put("password",pass); user.put("deptCode",deptCode); user.put("salt","Activeintelligence"); user.put("archiveMode", req.getHeader("archiveMode") != null ? req.getHeader("archiveMode") : false); user.put("owner",userName); user.put("isDatasource", true); user.put("isAdmin", true); } AuditLoggerUtil.log(AuditLoggerUtil.CORELOGGER, AuditLoggerUtil.INFO, FirstFilter.class, "User :"+userName +" logged in with traceid: "+ traceid, traceid, deptCode, null); responseData = new DefaultAuthenticateImpl().authenticated(user, deptCode); if (responseData == null || responseData.equalsIgnoreCase("Invalid Authentication")) { return; } else { res.setContentType("application/json"); res.setCharacterEncoding("UTF-8"); res.getWriter().print("[]"); res.setStatus(302); if (req.getServerPort() == 4200) { res.sendRedirect(req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + "/"+deptCode+"/sso_login?e="+responseData); } else { res.sendRedirect(req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + req.getContextPath() + "/"+deptCode+"/sso_login?e="+responseData); } } } else if (uri.contains("/embed/external/") && req.getQueryString() == null) { String responseData = null; String splits[] = uri.toString().split("/"); Map<String, Object> passData = new HashMap<>(); String deptCode = ""; for (String n : splits) { if (n.contains("a_d__") || n.contains("a_u__") || n.contains("a_p__")) { for (String n1 : n.split("&")) { if (n1.contains("a_d__")) { deptCode = n1.split("a_d__")[1]; passData.put("deptCode", deptCode); } else if (n1.contains("a_u__")) { passData.put("userName", n1.split("a_u__")[1]); } else if (n1.contains("a_p__")) { String p[] = n1.split("a_p__"); passData.put("password", p.length > 1 ? p[1] : null); } else if (n1.contains("a_t__")) { String p[] = n1.split("a_t__"); passData.put("token", p.length > 1 ? p[1] : null); } } } } passData.put("keyInfo", uri.toString().split("external/")[1].split("/")[0]); passData.put("isEmbed", true); //passData.putAll(new CommonConfig().getUserInfo(passData.get("userName").toString())); //res.addHeader("auth-token", passData.get("token").toString()); responseData = new DefaultAuthenticateImpl().authenticated(passData, deptCode); //res.addHeader("auth-token", "AIV"); if (responseData == null || responseData.equalsIgnoreCase("Invalid Authentication")) { return; } else { res.setContentType("application/json"); res.setCharacterEncoding("UTF-8"); res.addHeader("auth-token", passData.get("token").toString()); res.sendRedirect(req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() +uri+"?e="+responseData); } } else if (uri.contains("/embed/internal/") && req.getQueryString() == null) { chain.doFilter(req, res); return; } else if (uri.contains("/re_schedule_session")) { String oldtoken = req.getHeader("X-XSRFTOKEN") != null ? req.getHeader("X-XSRFTOKEN") : req.getParameter("X-XSRFTOKEN"); try { res.addHeader("auth-token", new JwtTokenUtil().extendTokenExpiration(oldtoken, new HeaderSecurity().getSessionTime())); } catch (Exception e) { res.getWriter().print("Session Expired"); AuditLoggerUtil.log(AuditLoggerUtil.SECURITYLOGGER, AuditLoggerUtil.ERROR, FirstFilter.class, "Something went wrong",traceid,"AUTH", e); return; } chain.doFilter(req, res); return; } else if (uri.contains("/v5/api/logout")) { res.getWriter().print(true); return; } else if (uri.contains("/v5") || uri.contains("file_upload_servlet") || uri.contains("download_file") || uri.contains("download_word_file") || uri.contains("export_excel") || uri.contains("image_upload_servlet") || uri.contains("zip_files") || uri.contains("load_document") || uri.contains("subreportrun") || uri.contains("execute_adhoc_report")) { if (req.getHeader("X-XSRFTOKEN") != null || req.getParameter("X-XSRFTOKEN") != null) { String oldtoken = req.getHeader("X-XSRFTOKEN") != null ? req.getHeader("X-XSRFTOKEN") : req.getParameter("X-XSRFTOKEN"); //res.addHeader("auth-token", new JwtTokenUtil().extendTokenExpiration(oldtoken, new HeaderSecurity().getSessionTime())); try { res.addHeader("auth-token", new JwtTokenUtil().extendTokenExpiration(oldtoken, new HeaderSecurity().getSessionTime())); } catch (Exception e) { res.getWriter().print("Session Expired"); AuditLoggerUtil.log(AuditLoggerUtil.SECURITYLOGGER, AuditLoggerUtil.ERROR, FirstFilter.class, "Something went wrong",traceid,"AUTH", e); return; } //new JwtTokenUtil().invalidateToken(oldtoken); chain.doFilter(req, res); return; } else if (req.getHeader("apitoken") != null) { chain.doFilter(req, res); return; } } else if (uri.contains("/v5/api/logout")) { res.getWriter().print(true); Map<String, Object> arr = new HashMap<String, Object>(); String stoken = req.getHeader("stoken") != null ? req.getHeader("stoken") : req.getParameter("stoken") != null ? req.getParameter("stoken") : null; if (stoken != null) { arr = new HeaderSecurity().getSTokenInfo(stoken,"AUTH",traceid); } JSONObject js = null; js = new JSONObject(new HeaderSecurity().fromHexString(arr.get("additional_token").toString())); //new JwtTokenUtil().invalidateToken(js.getString("token")); return; } else { if (req.getHeader("x-xsrftoken") != null) { String oldtoken = req.getHeader("x-xsrftoken"); if (oldtoken != null && !oldtoken.equalsIgnoreCase("")){ try { res.addHeader("auth-token", new JwtTokenUtil().extendTokenExpiration(oldtoken, new HeaderSecurity().getSessionTime())); } catch (Exception e) { res.getWriter().print("Session Expired"); AuditLoggerUtil.log(AuditLoggerUtil.SECURITYLOGGER, AuditLoggerUtil.ERROR, FirstFilter.class, "Something went wrong",traceid,"AUTH", e); return; } } String uName = req.getHeader("userName") != null ? req.getHeader("userName") : req.getParameter("userName") != null ? req.getParameter("userName") : "null"; String dc= req.getHeader("dc") != null ? req.getHeader("dc") : req.getParameter("dc") != null ? req.getParameter("dc") : "null"; // res.setHeader("auth-token", "AIV"); chain.doFilter(req, res); return; } else if (req.getHeader("apitoken") != null) { chain.doFilter(req, res); return; } else { chain.doFilter(req, res); return; } } } catch (Exception e) { AuditLoggerUtil.log(AuditLoggerUtil.CORELOGGER, AuditLoggerUtil.ERROR, FirstFilter.class, e.getMessage(), "AUTH", "", e); } } public boolean isAUth(HttpServletRequest req, HttpServletResponse res) { return true; } @Override public void destroy() { Filter.super.destroy(); } }
-
Embedded Request Authentication
If the login comes from an embedded url:
Parse the URL to get(In above example I have added):
- a_d__ → department
- a_u__ → username
- a_p__ → password (optional)
- a_t__ → token (optional)
-
Add required additional properties:
If you need to add additional properties please add it in application.yml file at ```
/econfig“ folder or you can add files there also if required. -
Important: In application.yml file please update below property.
app:
securityClass:
<class name which you implemented in step 3>
E.g: com.security.services.SimpleAuthImpl