Html5 routing with Spring and Angular - java

I'm trying to implement HTML5 routing with Spring-boot and Angular 1.5, following this article.
At some point I need to redirect all the angular routes to the base path with a controller like this:
#Controller
public class UrlController {
// Match everything without a suffix (so not a static resource)
#RequestMapping(value = "/{path:[^\\.]*}"))
public String redirect(HttpServletRequest request) {
// Forward to home page so that route is preserved.
return "forward:/";
}
}
While the regular expression matches most of the URLS, like dashboard, search etc:
2016-08-05 16:39:58 DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping:306 - Looking up handler method for path /dashboard
2016-08-05 16:39:58 DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping:313 - Returning handler method UrlController.redirect(javax.servlet.http.HttpServletRequest,java.lang.String)]
2016-08-05 16:39:58 DEBUG o.s.b.f.s.DefaultListableBeanFactory:251 - Returning cached instance of singleton bean 'urlController'
2016-08-05 16:39:58 DEBUG o.s.w.s.DispatcherServlet:947 - Last-Modified value for [/dashboard] is: -1
2016-08-05 16:39:58 DEBUG c.a.a.w.i.LoggingInterceptor:22 - Start processing url request: https://localhost:8443/dashboard
redirecting to home page from url https://localhost:8443/dashboard
2016-08-05 16:39:58 DEBUG c.a.a.w.i.LoggingInterceptor:35 - Finished processing url request: https://localhost:8443/dashboard, duration: 0[ms]
Others are ignored and not matched at all, like https://localhost:8443/faults/64539352
2016-08-05 17:00:05 DEBUG o.s.w.s.DispatcherServlet:861 - DispatcherServlet with name 'dispatcherServlet' processing GET request for [/faults/64539352]
2016-08-05 17:00:05 DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping:306 - Looking up handler method for path /faults/64539352
2016-08-05 17:00:05 DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping:316 - Did not find handler method for [/faults/64539352]
The regular expression seems to be fine if you test it in regexplanet
, but it does not match what I want if I put it in the #RequestMapping.
Does anybody know how to make it work, or even better how to do it without regular expressions?

The problem and solution is described here. The solution consist in the implementation of a OncePerRequestFilter where you can match the full URI against whatever you want.

You can use a correct PathMatcher to do the job: {path:(?:(?!api|.).)*}/**
More info here

Related

"Unauthorized: Full authentication is required to access this resource" when booting up the app

This is a bit annoying since I've solved the original problem (which was this) but now this is another thing that I can't quite debug myself.
I am using JHispter 6.10 (Spring Boot 2.2.7.RELEASE) + React for my project. I've recently come to the need of using entities as catalogues (so they can be managed easily by an admin) and they need to be used on the register page. My first problem was that they wouldn't the dropdown in the register page, but that problem had to do with SecurityConfiguration.java, so I added the entities to be permitted to All:
.antMatchers("/api/comunidad-famdals").permitAll()
.antMatchers("/api/ciudads").permitAll()
.antMatchers("/api/estados").permitAll()
.antMatchers("/api/ladrillo-famdals").permitAll()
.antMatchers("/api/pais").permitAll()
.antMatchers("/api/**").authenticated()
And that seems to work just fine, but the first time I load the app (in dev mode), it throws the next error:
2020-10-09 02:03:33.337 DEBUG 63312 --- [ XNIO-1 task-9] c.f.m.r.CustomAuditEventRepository : Enter: add() with argument[s] = [AuditEvent [timestamp=2020-10-09T07:03:33.302498Z, principal=anonymousUser, type=AUTHORIZATION_FAILURE, data={details=org.springframework.security.web.authentication.WebAuthenticationDetails#b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null, type=org.springframework.security.access.AccessDeniedException, message=Access is denied}]]
2020-10-09 02:03:33.342 DEBUG 63312 --- [ XNIO-1 task-9] c.f.m.r.CustomAuditEventRepository : Exit: add() with result = null
2020-10-09 02:03:33.473 WARN 63312 --- [ XNIO-1 task-9] o.z.problem.spring.common.AdviceTraits : Unauthorized: Full authentication is required to access this resource
2020-10-09 02:03:33.564 WARN 63312 --- [ XNIO-1 task-9] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.security.authentication.InsufficientAuthenticationException: Full authentication is required to access this resource]
And when trying to register, the dropdown still doesn't show anything:
But if I go home once again, the terminal shows that all the queries have been done correctly, and sure enough, if I go back to the register page:
I would like to know if I am missing something on my SecurityConfiguration.java or if the order of the configuration needs to be different for it to work properly.
you have to give permissions to your endpoint in the Spring Boot Configuration (SecurityConfiguration.java)
add a new antMatchers parameter to the HttpSecurity.authorizeRequests() it should look like this:
http
.authorizeRequests()
.antMatchers("/api/yourEndpoint").permitAll()
of course you have to select who has authority to call this endpoint
Hope it works for you :)

Spring LDAP authentication NO_OBJECT

I am trying to connect a Spring application to an AD-LDAP server. If I type the correct user/pass-data I get NO_OBJECT-error in the log:
DEBUG o.s.s.l.s.FilterBasedLdapUserSearch - Searching for user 'THEUSER', with user search [ searchFilter: '(sAMAccountName={0})', searchBase: 'DC=dev,DC=company,DC=local', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]
DEBUG o.s.s.l.SpringSecurityLdapTemplate - Searching for entry under DN '', base = 'dc=entwicklung,dc=Lemken,dc=local', filter = '(sAMAccountName={0})'
DEBUG o.s.s.l.SpringSecurityLdapTemplate - Found DN: CN=THEUSER\, FirstName,OU=users,DC=dev,DC=company,DC=local
DEBUG o.s.s.l.a.BindAuthenticator - Attempting to bind as cn=THEUSER\, FirstName,ou=users,dc=dev,dc=company,dc=local
DEBUG o.s.s.l.DefaultSpringSecurityContextSource - Removing pooling flag for user cn=THEUSER\, FirstName,ou=users,dc=dev,dc=company,dc=local
DEBUG o.s.s.l.u.DefaultLdapAuthoritiesPopulator - Getting authorities for user cn=THEUSER\, FirstName,ou=users,dc=dev,dc=company,dc=local
DEBUG o.s.s.l.u.DefaultLdapAuthoritiesPopulator - Searching for roles for user 'THEUSER', DN = 'cn=THEUSER\, FirstName,ou=users,dc=dev,dc=company,dc=local', with filter (uniqueMember={0}) in search base ''
DEBUG o.s.s.l.SpringSecurityLdapTemplate - Using filter: (uniqueMember=cn=THEUSER\5c, FirstName,ou=users,dc=dev,dc=company,dc=local)
ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
org.springframework.ldap.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-03100213, problem 2001 (NO_OBJECT), data 0, best match of:
''
This is my configuration:
ContextSourceBuilder context = auth.ldapAuthentication()
.userSearchFilter("(sAMAccountName={0})")
.userSearchBase("dc=dev,dc=company,dc=local")
.contextSource();
context.port(389);
context
.root("dc=dev,dc=company,dc=local")
.url("ldap://example.com")
.managerDn("cn=manager,ou=users,dc=dev,dc=company,dc=local")
.managerPassword("thepassword");
If i type a wrong password I get "Bad password", so this part works.
What am I doing wrong?
The key parts are:
Searching for roles
...
Using filter: (uniqueMember=
It is trying to find the user's roles - in AD those are the groups that the user is a member of. But it's doing that by searching groups that have the uniqueMember attribute set to the user. That attribute doesn't exist in AD. That is the default attribute name it uses since that's what's used in OpenLDAP.
You will need to use groupSearchFilter() to change the attribute it looks at to find groups. AD uses the member attribute.
ContextSourceBuilder context = auth.ldapAuthentication()
.userSearchFilter("(sAMAccountName={0})")
.userSearchBase("dc=dev,dc=company,dc=local")
.groupSearchFilter("(member={0})")
.contextSource();

Freemarker Template Not Found in Dropwizard Intellij

I'm trying to set up a freemarker template to show the results of a SQL query. I'm running into an issue where Intellij is reporting that the template cannot be found:
DEBUG [2018-02-27 18:52:31,623] freemarker.cache: Couldn't find template in cache for "com/example/www/resources/template.ftl"("en_US", ISO-8859-1, parsed); will try to load it.
DEBUG [2018-02-27 18:52:31,624] freemarker.cache: TemplateLoader.findTemplateSource("com/example/www/resources/template_en_US.ftl"): Not found
DEBUG [2018-02-27 18:52:31,626] freemarker.cache: TemplateLoader.findTemplateSource("com/example/www/resources/template_en.ftl"): Not found
DEBUG [2018-02-27 18:52:31,627] freemarker.cache: TemplateLoader.findTemplateSource("com/example/www/resources/template.ftl"): Not found
DEBUG [2018-02-27 18:52:31,661] org.eclipse.jetty.server.handler.gzip.GzipHttpOutputInterceptor: org.eclipse.jetty.server.handler.gzip.GzipHttpOutputInterceptor#f62788 exclude by status 404
DEBUG [2018-02-27 18:52:31,662] org.eclipse.jetty.server.HttpChannel: sendResponse info=null content=HeapByteBuffer#d1e062[p=0,l=248,c=32768,r=248]={<<<<html>\n<head>\n<me.../body>\n</html>\n>>>\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00...\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00} complete=true committing=true callback=Blocker#4fab4a{null}
DEBUG [2018-02-27 18:52:31,662] org.eclipse.jetty.server.HttpChannel: COMMIT for /address/3 on HttpChannelOverHttp#a67c6b{r=1,c=true,a=DISPATCHED,uri=//localhost:8080/address/3}
404 Not Found HTTP/1.1
Date: Tue, 27 Feb 2018 18:52:31 GMT
Cache-Control: must-revalidate,no-cache,no-store
Content-Type: text/html;charset=iso-8859-1
This happened when my main method in my app class was set up like so:
public class AppApplication extends Application<AppConfiguration> {
public static void main(final String[] args) throws Exception {
new AppApplication().run(args);
}
Under this setup, navigating to the URL that returns an address database returns a 404 error in my browser and the above logs in debug mode.
Additional research into using Freemarker in Dropwizard led me to setting up a Configuration instance in the main method of the app to look for the template with setDirectoryForTemplateLoading, to point to the path, and to use getTemplate to return the template file itself:
public class AppApplication extends Application<AppConfiguration> {
public static void main(final String[] args) throws Exception {
Configuration cfg = new Configuration(Configuration.VERSION_2_3_27);
cfg.setDirectoryForTemplateLoading(new File("C:\\IdeaProjects\\App\\src\\main\\resources"));
cfg.getTemplate("template.ftl");
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
cfg.setLogTemplateExceptions(false);
cfg.setWrapUncheckedExceptions(true);
new AppApplication().run(args);
}
However, going to the URL returns the same error. The only discernible difference in this case is that the info for the error is printed at the top of the console as the server starts:
14:09:24.891 [main] DEBUG freemarker.cache - Couldn't find template in cache for "template.ftl"("en_US", UTF-8, parsed); will try to load it.
14:09:24.907 [main] DEBUG freemarker.cache - TemplateLoader.findTemplateSource("template_en_US.ftl"): Not found
14:09:24.907 [main] DEBUG freemarker.cache - TemplateLoader.findTemplateSource("template_en.ftl"): Not found
14:09:24.907 [main] DEBUG freemarker.cache - TemplateLoader.findTemplateSource("template.ftl"): Found
14:09:24.922 [main] DEBUG freemarker.cache - Loading template for "template.ftl"("en_US", UTF-8, parsed) from "C:\\IdeaProjects\\App\\src\\main\\resources\\template.ftl"
At the end, it shows that is it loading the template from the resource folder; However, trying to run the getter methods I've defined returns the same error later on in the console. Can anyone give me some insight on this? I don't think its an issue with my code, but rather that the .ftl file isn't regestering to Intellij.
Edit: Here is my View Bundle, under initialize.:
bootstrap.addBundle(new ViewBundle<AppConfiguration>() {
public Map<String, Map<String, String>> getViewConfiguration(AppConfiguration configuration) {
return configuration.getViewRendererConfiguration();
}
});

Spring Oauth2 RemoteTokenServices error on extractAuthentication

I have a resource server and an auth server.
On resource request it verifies the received access_token with the auth server on a /oauth/check_token endpoint. This gives a response that makes my request crash.
The response is sent as:
Written [{exp=1433335640, scope=[read, write], authorities=[ROLE_USER], client_id=client-w-s}] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#58a88f5a]
When my resource server receives it:
2015-06-03 14:17:48.277 DEBUG 9492 --- [nio-8181-exec-3] o.s.web.client.RestTemplate : POST request for "http://localhost:6707/oauth/check_token" resulted in 200 (OK)
2015-06-03 14:17:48.277 DEBUG 9492 --- [nio-8181-exec-3] o.s.web.client.RestTemplate : Reading [interface java.util.Map] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#67409450]
2015-06-03 14:17:48.283 ERROR 9492 --- [nio-8181-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
java.lang.ArrayStoreException: null
at java.util.ArrayList.toArray(Unknown Source)
at org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter.extractAuthentication(DefaultAccessTokenConverter.java:139)
This is the piece of code it fails on:
Collection<? extends GrantedAuthority> authorities = null;
if (user==null && map.containsKey(AUTHORITIES)) {
#SuppressWarnings("unchecked")
String[] roles = ((Collection<String>)map.get(AUTHORITIES)).toArray(new String[0]);
authorities = AuthorityUtils.createAuthorityList(roles);
}
I ran in debug mode to check the values in map, and everything looks like I think it should judging from the response my auth server built.
Please tell me if I need to post more information.
Has anyone experienced this or have any clue on how to solve it?
I found the "solution".
There was a version mismatch in my pom files. While my auth server was running spring-security-oauth2-2.0.5.RELEASE my resource server was running spring-security-oauth2-2.0.7.RELEASE .
The versions declare the response differently.
I think there is an error in DefaultAccessTokenConverter implementation, since spring-security-oauth2 2.0.7.RELEASE, because of this line:
if (user==null && map.containsKey(AUTHORITIES)) {
...
}
Why the "user==null" condition?
The "user" variable isn't null, so the condition is never true, and the authorities array is not filled.
I think this is a Spring Security Oauth2 implementation error.

Unable to secure Spring boot management actuator endpoints

I am trying to secure the Spring Boot actuactor endpoints. I have working security on my /api REST interface, but trying to add security on the built-in endpoints does not seem to work.
I have set up grouping of the endpoints in my application.properties:
management.context-path=/management
I have this in my Java Config
#Override
protected void configure( HttpSecurity http ) throws Exception
{
http.csrf().disable();
http.sessionManagement().sessionCreationPolicy( SessionCreationPolicy.STATELESS );
http.authorizeRequests()
.antMatchers( "/api/**" ).hasRole( "READONLY" )
.antMatchers( "/management/**" ).hasRole( "ADMIN" );
SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity> securityConfigurer = new XAuthTokenConfigurer( userDetailsServiceBean() );
http.apply( securityConfigurer );
}
When I use my browser to go to anything below /api, I get a 403 back as expected. When going to /management/info for example, I see the JSON being returned where I would also expect a 403.
I also tried adding this to my application.properties file:
management.security.role=ADMIN
But that did not help either.
The DEBUG output shows:
2014-05-02 10:15:30 DEBUG [localhost-startStop-1] ExpressionBasedFilterInvocationSecurityMetadataSource -
Adding web access control expression 'hasRole('ROLE_READONLY')', for Ant [pattern='/api/**']
2014-05-02 10:15:30 DEBUG [localhost-startStop-1] ExpressionBasedFilterInvocationSecurityMetadataSource -
Adding web access control expression 'hasRole('ROLE_ADMIN')', for Ant [pattern='/management/**']
And then why I try the HTTP GET:
2014-05-02 10:16:39 DEBUG [http-nio-8443-exec-4] AntPathRequestMatcher - Checking match of request : '/management/info'; against '/css/**'
2014-05-02 10:16:39 DEBUG [http-nio-8443-exec-4] AntPathRequestMatcher - Checking match of request : '/management/info'; against '/js/**'
2014-05-02 10:16:39 DEBUG [http-nio-8443-exec-4] AntPathRequestMatcher - Checking match of request : '/management/info'; against '/images/**'
2014-05-02 10:16:39 DEBUG [http-nio-8443-exec-4] AntPathRequestMatcher - Checking match of request : '/management/info'; against '/**/favicon.ico'
2014-05-02 10:16:39 DEBUG [http-nio-8443-exec-4] AntPathRequestMatcher - Checking match of request : '/management/info'; against '/management/info'
2014-05-02 10:16:39 DEBUG [http-nio-8443-exec-4] FilterChainProxy - /management/info has an empty filter list
The log that tells the story is: "/management/info has an empty filter list" because it is explicitly marked as ignored (/info is always supposed to be available). Try one of the other actuator endpoints and see if those behave as you expect. If you really need to secure the info endpoint you can set endpoints.info.sensitive=true (I think).

Categories

Resources