{"id":117,"date":"2019-04-24T10:41:04","date_gmt":"2019-04-24T10:41:04","guid":{"rendered":"https:\/\/www.samarthya.me\/wps\/?p=117"},"modified":"2019-04-24T10:41:04","modified_gmt":"2019-04-24T10:41:04","slug":"spring-data-ldap","status":"publish","type":"post","link":"https:\/\/blog.samarthya.me\/wps\/2019\/04\/24\/spring-data-ldap\/","title":{"rendered":"Spring Data-LDAP"},"content":{"rendered":"<p>I have a small problem at hand which girdles around learning Angular, with a Spring enabled Rest endpoints which uses a DB to store data and have security layer in between that should interact with a LDAP for authentication and authorization and finally the application should run as one smooth unit. It will be too much to cover in single blog so I will be writing multiple blogs in continuation to this one.<\/p>\n<p>There\u00a0were\u00a0multiple\u00a0start\u00a0points\u00a0that\u00a0I\u00a0could\u00a0have\u00a0started\u00a0but\u00a0in retrospect\u00a0as\u00a0I\u00a0blog\u00a0about\u00a0it, the\u00a0best\u00a0starting\u00a0point\u00a0is\u00a0to think about the\u00a0services\u00a0alone\u00a0at\u00a0first, what\u00a0you\u00a0want to\u00a0develop\u00a0and create\u00a0them\u00a0independently\u00a0and\u00a0test\u00a0them\u00a0as\u00a0a\u00a0unit\u00a0before\u00a0you\u00a0can\u00a0proceed\u00a0to\u00a0any\u00a0other\u00a0component.<\/p>\n<p>The other way could have been, that I define the functional signature and agree on expectation, especially if it was more than one team member project and it would have been much easier to develop parallely.<\/p>\n<p>Anyway,\u00a0I\u00a0am\u00a0just\u00a0using\u00a0my\u00a0spare\u00a0time\u00a0to\u00a0develop\u00a0it, so\u00a0I\u00a0thought\u00a0of crunching\u00a0some sample\u00a0code to\u00a0try\u00a0out\u00a0the\u00a0service that\u00a0I\u00a0wanted before\u00a0jumping\u00a0on\u00a0the\u00a0actual\u00a0application.<\/p>\n<p>Starting\u00a0point as\u00a0 always\u00a0is\u00a0sprint\u00a0initializer and\u00a0it helped\u00a0me\u00a0chose\u00a0what\u00a0I\u00a0want and get\u00a0the\u00a0guideline\u00a0project\u00a0to\u00a0start\u00a0with.<\/p>\n<blockquote>\n<div class=\"cm-replace _replace_01\">\n<p>&lt;dependencies&gt;<br \/>\n&lt;dependency&gt;<br \/>\n&lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;<br \/>\n&lt;artifactId&gt;spring-boot-starter-data-ldap&lt;\/artifactId&gt;<br \/>\n&lt;\/dependency&gt;<br \/>\n&lt;dependency&gt;<br \/>\n&lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;<br \/>\n&lt;artifactId&gt;spring-boot-starter-data-rest&lt;\/artifactId&gt;<br \/>\n&lt;\/dependency&gt;<br \/>\n&lt;dependency&gt;<br \/>\n&lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;<br \/>\n&lt;artifactId&gt;spring-boot-starter-security&lt;\/artifactId&gt;<br \/>\n&lt;\/dependency&gt;<br \/>\n&lt;dependency&gt;<br \/>\n&lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;<br \/>\n&lt;artifactId&gt;spring-boot-starter-web&lt;\/artifactId&gt;<br \/>\n&lt;\/dependency&gt;<\/p>\n<p>&lt;dependency&gt;<br \/>\n&lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;<br \/>\n&lt;artifactId&gt;spring-boot-starter-tomcat&lt;\/artifactId&gt;<br \/>\n&lt;scope&gt;provided&lt;\/scope&gt;<br \/>\n&lt;\/dependency&gt;<br \/>\n&lt;dependency&gt;<br \/>\n&lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;<br \/>\n&lt;artifactId&gt;spring-boot-starter-test&lt;\/artifactId&gt;<br \/>\n&lt;scope&gt;test&lt;\/scope&gt;<br \/>\n&lt;\/dependency&gt;<br \/>\n&lt;dependency&gt;<br \/>\n&lt;groupId&gt;org.springframework.security&lt;\/groupId&gt;<br \/>\n&lt;artifactId&gt;spring-security-test&lt;\/artifactId&gt;<br \/>\n&lt;scope&gt;test&lt;\/scope&gt;<br \/>\n&lt;\/dependency&gt;<br \/>\n&lt;\/dependencies&gt;<\/p>\n<\/div>\n<\/blockquote>\n<p>Since I have added\u00a0these dependencies now, and am using IntelliJ to develop, life becomes a little easier.<\/p>\n<p>The current code looks minimal with the two classes<\/p>\n<blockquote>\n<div class=\"cm-replace _replace_11\">\n<p>@SpringBootApplication<br \/>\npublic class EventsServicesApplication {<\/p>\n<p>public static void main(String[] args) {<br \/>\nSpringApplication.run(EventsServicesApplication.class, args);<br \/>\n}<\/p>\n<p>}<\/p>\n<\/div>\n<\/blockquote>\n<p>and<\/p>\n<blockquote>\n<div class=\"cm-replace _replace_31\">\n<p>public class ServletInitializer extends SpringBootServletInitializer {<\/p>\n<p>@Override<br \/>\nprotected SpringApplicationBuilder configure(SpringApplicationBuilder application) {<br \/>\nreturn application.sources(EventsServicesApplication.class);<br \/>\n}<\/p>\n<p>}<\/p>\n<\/div>\n<\/blockquote>\n<p>So scaffolding\u00a0is\u00a0ready,\u00a0and it is\u00a0time\u00a0to\u00a0add\u00a0some\u00a0dummy capabilities\u00a0to\u00a0try\u00a0out.<\/p>\n<p>You can configure few properties in the <em>application.properties<\/em> file<\/p>\n<blockquote>\n<div class=\"cm-replace _replace_41\">spring.profiles.active=default<br \/>\nserver.port=8082<br \/>\nserver.servlet.context-path=\/events<br \/>\nlogging.level.org.springframework=DEBUG<\/div>\n<\/blockquote>\n<p>If you now execute you can watch out for the information in the console that can help you understand what is getting initialized and how the spring framework is helping to stitch the capability that we are trying to achieve.<\/p>\n<blockquote>\n<div class=\"cm-replace _replace_51\">2019-04-23 23:15:10.932 INFO 62835 &#8212; [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8082 (http) with context path &#8216;\/events&#8217;<br \/>\n2019-04-23 23:15:10.938 INFO 62835 &#8212; [ main] m.s.E.EventsServicesApplication : Started EventsServicesApplication in 3.486 seconds (JVM running for 4.881)<\/div>\n<\/blockquote>\n<p>I added my first controller a\u00a0<a href=\"https:\/\/docs.spring.io\/spring\/docs\/current\/javadoc-api\/org\/springframework\/web\/bind\/annotation\/RestController.html\">RestController<\/a><\/p>\n<blockquote>\n<div class=\"cm-replace _replace_101\">\n<p>@RestController<br \/>\npublic class ControllerOne {<\/p>\n<p>@GetMapping(&#8220;\/&#8221;)<br \/>\n@ResponseBody<br \/>\npublic String bonsoir(@RequestParam(name = &#8220;id&#8221;, required = false) String id, HttpServletRequest request) {<br \/>\nif(id != null )<br \/>\nreturn &#8220;Bonsoir &#8221; + id + &#8221; !&#8221;;<br \/>\nelse<br \/>\nreturn &#8220;Bonsoir!&#8221;;<br \/>\n}<\/p>\n<p>@ResponseBody<br \/>\n@GetMapping(&#8220;\/error&#8221;)<br \/>\npublic String errorMessage(HttpServletRequest request) {<br \/>\nreturn &#8220;Error occurred, please see the server logs.&#8221;;<br \/>\n}<br \/>\n}<\/p>\n<\/div>\n<\/blockquote>\n<p>At\u00a0this\u00a0moment\u00a0if\u00a0you\u00a0try\u00a0to call the endpint\u00a0using any\u00a0of\u00a0the\u00a0rest\u00a0clients (your preference, but I use insomnia)\u00a0 in this\u00a0application you\u00a0may see\u00a0something\u00a0like\u00a0below<\/p>\n<blockquote>\n<div class=\"cm-replace _replace_71\">&gt; GET \/events HTTP\/1.1<br \/>\n&gt; Host: localhost:8082<br \/>\n&gt; User-Agent: insomnia\/6.3.2<br \/>\n&gt; Cookie: JSESSIONID=67570EB8C6F2A822F908C4A9F1CBA2E7<br \/>\n&gt; Accept: *\/*<\/div>\n<\/blockquote>\n<p>Response would be<\/p>\n<blockquote><p>&lt; HTTP\/1.1 401<br \/>\n&lt; Set-Cookie: JSESSIONID=DBC2F7DF3DBE01D6E3B45E9B311ABB66; Path=\/events; HttpOnly<br \/>\n&lt; WWW-Authenticate: Basic realm=&#8221;Realm&#8221;<br \/>\n&lt; X-Content-Type-Options: nosniff<br \/>\n&lt; X-XSS-Protection: 1; mode=block<br \/>\n&lt; Cache-Control: no-cache, no-store, max-age=0, must-revalidate<br \/>\n&lt; Pragma: no-cache<br \/>\n&lt; Expires: 0<br \/>\n&lt; X-Frame-Options: DENY<br \/>\n&lt; Content-Type: application\/json;charset=UTF-8<br \/>\n&lt; Transfer-Encoding: chunked<br \/>\n&lt; Date: Tue, 23 Apr 2019 17:47:07 GMT<\/p><\/blockquote>\n<p>It\u00a0is\u00a0simply\u00a0because\u00a0we\u00a0have\u00a0enabled\u00a0the\u00a0security which\u00a0enforces\u00a0all\u00a0the\u00a0request\u00a0that\u00a0is\u00a0being sent\u00a0to\u00a0this\u00a0server\u00a0are\u00a0being\u00a0scrutnized\u00a0and\u00a0by\u00a0default the\u00a0value that\u00a0it uses\u00a0for\u00a0the\u00a0<a href=\"https:\/\/docs.spring.io\/spring-security\/site\/docs\/current\/api\/org\/springframework\/security\/config\/annotation\/web\/configuration\/WebSecurityConfigurerAdapter.html\">WebSecurityConfigurerAdapter<\/a>\u00a0is\u00a0below<\/p>\n<blockquote>\n<div class=\"cm-replace _replace_251\">http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().httpBasic();<\/div>\n<\/blockquote>\n<p>All request that reach the server are\u00a0all evaluated for\u00a0the\u00a0right Access.<\/p>\n<blockquote>\n<div class=\"cm-replace _replace_91\">org.springframework.security.access.AccessDeniedException: Access is denied<br \/>\nat org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:124) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]<br \/>\nat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter.doFilterInternal(DefaultLogoutPageGeneratingFilter.java:52) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]<br \/>\nat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:206) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]<br \/>\nat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]<br \/>\nat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]<br \/>\nat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) [spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]<br \/>\nat org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]<br \/>\nat org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]<br \/>\nat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]<br \/>\nat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]<br \/>\nat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]<br \/>\nat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]<br \/>\nat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]<br \/>\nat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]<br \/>\nat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]<br \/>\nat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]<br \/>\nat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat java.base\/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) [na:na]<br \/>\nat java.base\/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) [na:na]<br \/>\nat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.17.jar:9.0.17]<br \/>\nat java.base\/java.lang.Thread.run(Thread.java:844) [na:na]<\/div>\n<\/blockquote>\n<p>Time\u00a0to customize\u00a0<a href=\"https:\/\/docs.spring.io\/spring-security\/site\/docs\/current\/api\/org\/springframework\/security\/config\/annotation\/web\/configuration\/WebSecurityConfigurerAdapter.html\">security<\/a><\/p>\n<p>I\u00a0started\u00a0by\u00a0adding extending the <a href=\"https:\/\/docs.spring.io\/spring-security\/site\/docs\/current\/api\/org\/springframework\/security\/config\/annotation\/web\/configuration\/WebSecurityConfigurerAdapter.html\">WebSecurityConfigurerAdapter<\/a><\/p>\n<blockquote>\n<div class=\"cm-replace _replace_141\">@Configuration<br \/>\n@EnableWebSecurity(debug = true)<br \/>\npublic class WebSecurityConfig extends WebSecurityConfigurerAdapter {<br \/>\n@Override<br \/>\nprotected void configure(HttpSecurity http) throws Exception {<br \/>\nhttp.authorizeRequests().anyRequest().permitAll();<br \/>\n}<br \/>\n}<\/div>\n<\/blockquote>\n<p>What I have done in the configure method is bypassed all the security explicitly by stating that permits all the requests with the overridden configure method.<\/p>\n<h2>Spring\u00a0Data\u00a0Ldap<\/h2>\n<p>Now time to start with the Ldap structuring. From the introduction available at <a href=\"https:\/\/spring.io\/projects\/spring-data-ldap\">spring.io<\/a><\/p>\n<blockquote>\n<div class=\"cm-replace _replace_161\">The Spring Data LDAP project provides repository abstractions for Spring LDAP<br \/>\non top of Spring LDAP\u2019s LdapTemplate and Object-Directory Mapping.<\/div>\n<\/blockquote>\n<p>Object-relational mapping frameworks like Hibernate and JPA offers developers the ability to use annotations to map relational database tables to Java objects.Spring LDAP project offers a similar ability with respect to LDAP directories through a number of methods: in <code>LdapOperations<\/code><\/p>\n<p>Also,\u00a0note<\/p>\n<blockquote>\n<div class=\"cm-replace _replace_171\">Spring LDAP repositories can be enabled by using a &lt;data-ldap:repositories&gt;<br \/>\ntag in your XML configuration or by using an @EnableLdapRepositories annotation<br \/>\non a configuration class.<\/div>\n<\/blockquote>\n<p>For Ldap source I am using apacheDS which is fairly easy to use and manage.<\/p>\n<p><img decoding=\"async\" class=\"fr-fin fr-dib aligncenter\" src=\"https:\/\/dzone.com\/storage\/temp\/11718636-screenshot-2019-04-24-at-122059-pm.png\" alt=\"Image title\" width=\"300\" \/><\/p>\n<p>With\u00a0a\u00a0typical\u00a0user attributes\u00a0as\u00a0under<\/p>\n<p><img decoding=\"async\" class=\"fr-fin fr-dib aligncenter\" src=\"https:\/\/dzone.com\/storage\/temp\/11718641-screenshot-2019-04-24-at-122213-pm.png\" alt=\"Image title\" width=\"473\" \/><\/p>\n<p>Points\u00a0to\u00a0remember\u00a0straight\u00a0from\u00a0the\u00a0documentation<\/p>\n<ol>\n<li>All Spring LDAP repositories must work with entities annotated with the ODM annotations, as described in <a href=\"https:\/\/docs.spring.io\/spring-ldap\/docs\/2.3.2.RELEASE\/reference\/#odm\">Object-Directory Mapping<\/a>.<\/li>\n<li>Since all ODM managed classes must have a Distinguished Name as the ID, all Spring LDAP repositories must have the ID type parameter set to <code>javax.naming.Name<\/code>. Indeed, the built-in <code>LdapRepository<\/code> only takes one type parameter: the managed entity class, which defaults the ID to <code>javax.naming.Name<\/code>.<\/li>\n<li>Due to specifics of the LDAP protocol, paging and sorting are not supported for Spring LDAP repositories.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ul>\n<li>I wanted to try out user listing first, so first\u00a0thing\u00a0I\u00a0need\u00a0to\u00a0define\u00a0is\u00a0the\u00a0ODM\u00a0for the user.<\/li>\n<li>1. Added the maven dependency<\/li>\n<\/ul>\n<blockquote><p>&lt;dependency&gt;<br \/>\n&lt;groupId&gt;org.springframework.ldap&lt;\/groupId&gt;<br \/>\n&lt;artifactId&gt;spring-ldap-core&lt;\/artifactId&gt;<br \/>\n&lt;\/dependency&gt;<br \/>\n&lt;dependency&gt;<br \/>\n&lt;groupId&gt;org.springframework.data&lt;\/groupId&gt;<br \/>\n&lt;artifactId&gt;spring-data-ldap&lt;\/artifactId&gt;<br \/>\n&lt;\/dependency&gt;<\/p><\/blockquote>\n<p>Added\u00a0the\u00a0Entity\u00a0class\u00a0with\u00a0the\u00a0right\u00a0annotation<\/p>\n<blockquote>\n<div class=\"cm-replace _replace_201\">\n<p>@Entry(base=&#8221;ou=users&#8221;, objectClasses = {<br \/>\n&#8220;top&#8221;,<br \/>\n&#8220;inetOrgPerson&#8221;, &#8220;person&#8221;, &#8220;organizationalPerson&#8221;,<br \/>\n&#8220;simpleSecurityObject&#8221;})<br \/>\npublic class UserModel {<\/p>\n<p>@JsonIgnore<br \/>\n@Id<br \/>\nprivate Name id;<\/p>\n<p>@JsonProperty(&#8220;userName&#8221;)<br \/>\nprivate @Attribute(name = &#8220;uid&#8221;) String uid;<\/p>\n<p>@JsonProperty(&#8220;firstName&#8221;)<br \/>\nprivate @Attribute(name = &#8220;cn&#8221;) String firstName;<\/p>\n<p>@JsonIgnore<br \/>\nprivate @Attribute(name = &#8220;displayname&#8221;) String displayName;<\/p>\n<p>@JsonProperty(&#8220;lastName&#8221;)<br \/>\nprivate @Attribute(name = &#8220;sn&#8221;) String lastName;<\/p>\n<p>public UserModel(String uid, String firstName, String displayName, String lastName) {<br \/>\nthis.uid = uid;<br \/>\nthis.firstName = firstName;<br \/>\nthis.displayName = displayName;<br \/>\nthis.lastName = lastName;<br \/>\n}<\/p>\n<p>public UserModel(String userName, String firstName, String lastName) {<br \/>\nthis.uid = userName;<br \/>\nthis.firstName = firstName;<br \/>\nthis.lastName = lastName;<br \/>\n}<\/p>\n<p>public UserModel() {<\/p>\n<p>}<\/p>\n<p>public String getFirstName() {<br \/>\nreturn firstName;<br \/>\n}<\/p>\n<p>public void setFirstName(String firstName) {<br \/>\nthis.firstName = firstName;<br \/>\n}<\/p>\n<p>public String getLastName() {<br \/>\nreturn lastName;<br \/>\n}<\/p>\n<p>public void setLastName(String lastName) {<br \/>\nthis.lastName = lastName;<br \/>\n}<\/p>\n<p>public String getUid() {<br \/>\nreturn uid;<br \/>\n}<\/p>\n<p>public void setUid(String uid) {<br \/>\nthis.uid = uid;<br \/>\n}<\/p>\n<p>public String getDisplayName() {<br \/>\nreturn displayName;<br \/>\n}<\/p>\n<p>public void setDisplayName(String displayName) {<br \/>\nthis.displayName = displayName;<br \/>\n}<\/p>\n<p>@Override<br \/>\npublic String toString() {<br \/>\nreturn &#8220;UserModel{&#8221; +<br \/>\n&#8220;uid='&#8221; + uid + &#8216;\\&#8221; +<br \/>\n&#8220;, firstName='&#8221; + firstName + &#8216;\\&#8221; +<br \/>\n&#8220;, displayName='&#8221; + displayName + &#8216;\\&#8221; +<br \/>\n&#8220;, lastName='&#8221; + lastName + &#8216;\\&#8221; +<br \/>\n&#8216;}&#8217;;<br \/>\n}<br \/>\n}<\/p>\n<\/div>\n<\/blockquote>\n<p>Added configuration<\/p>\n<blockquote>\n<div class=\"cm-replace _replace_211\">@Configuration<br \/>\n@EnableLdapRepositories(basePackages = &#8220;me.samarthya.EventsServices.ldap&#8221;)<br \/>\npublic class ApacheDSConfiguration {<br \/>\n@Bean<br \/>\nLdapTemplate ldapTemplate(ContextSource contextSource) {<br \/>\nreturn new LdapTemplate(contextSource);<br \/>\n}<br \/>\n}<\/div>\n<\/blockquote>\n<p>Added\u00a0properties<\/p>\n<blockquote>\n<div class=\"cm-replace _replace_261\">spring.ldap.base=dc=example,dc=com<br \/>\nspring.ldap.password=secret<br \/>\nspring.ldap.username=uid=admin,ou=system<br \/>\nspring.ldap.urls=ldap:\/\/localhost:10389<\/div>\n<\/blockquote>\n<p>Created\u00a0repository<\/p>\n<blockquote>\n<div class=\"cm-replace _replace_221\">\n<p>@Repository<br \/>\npublic interface ApacheDSRepository extends LdapRepository&lt;UserModel&gt; {<\/p>\n<p>}<\/p>\n<\/div>\n<\/blockquote>\n<p>Added\u00a0a\u00a0method\u00a0in\u00a0the\u00a0controller\u00a0to\u00a0get\u00a0the\u00a0user\u00a0list.<\/p>\n<blockquote><p>@ResponseBody<br \/>\n@GetMapping(&#8220;\/users&#8221;)<br \/>\npublic Iterable&lt;UserModel&gt; getAllUsers() {<br \/>\nreturn apacheDSRepository.findAll();<br \/>\n}<\/p><\/blockquote>\n<div class=\"cm-replace _replace_231\"><\/div>\n<p>Firewaway\u00a0any\u00a0request\u00a0to\u00a0find\u00a0the\u00a0information<\/p>\n<blockquote><p>&gt; GET \/events\/users HTTP\/1.1<br \/>\n&gt; Host: localhost:8082<br \/>\n&gt; User-Agent: insomnia\/6.3.2<br \/>\n&gt; Cookie: JSESSIONID=438BF9E64596D6A1F96F49E7302BB8A9; JSESSIONID=67570EB8C6F2A822F908C4A9F1CBA2E7<br \/>\n&gt; Accept: *\/*<\/p>\n<p>&lt; HTTP\/1.1 200<br \/>\n&lt; X-Content-Type-Options: nosniff<br \/>\n&lt; X-XSS-Protection: 1; mode=block<br \/>\n&lt; Cache-Control: no-cache, no-store, max-age=0, must-revalidate<br \/>\n&lt; Pragma: no-cache<br \/>\n&lt; Expires: 0<br \/>\n&lt; X-Frame-Options: DENY<br \/>\n&lt; Content-Type: application\/json;charset=UTF-8<br \/>\n&lt; Transfer-Encoding: chunked<br \/>\n&lt; Date: Wed, 24 Apr 2019 09:02:06 GMT<\/p><\/blockquote>\n<div class=\"cm-replace _replace_241\"><\/div>\n<p><img decoding=\"async\" class=\"fr-fin fr-dib aligncenter\" title=\"Response received\" src=\"https:\/\/dzone.com\/storage\/temp\/11719231-screenshot-2019-04-24-at-35124-pm.png\" alt=\"Response received\" width=\"562\" \/><\/p>\n<p>If\u00a0you wish\u00a0to\u00a0see\u00a0the\u00a0code it\u00a0is\u00a0available\u00a0in\u00a0<a href=\"https:\/\/github.com\/samarthya\/EventsService\">github.com<\/a><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I have a small problem at hand which girdles around learning Angular, with a Spring enabled Rest endpoints which uses a DB to store data and have security layer in between that should interact with a LDAP for authentication and authorization and finally the application should run as one smooth unit. It will be too [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":118,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[1],"tags":[16,15],"class_list":["post-117","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-others","tag-security","tag-spring"],"_links":{"self":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts\/117","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/comments?post=117"}],"version-history":[{"count":0,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts\/117\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/media\/118"}],"wp:attachment":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/media?parent=117"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/categories?post=117"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/tags?post=117"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}