I'm building spring mvc application with spring security.
This is my url :
http://localhost:8080/inbalUI/login
And I'm getting to my controller :
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String loginPage() {
if (isCurrentAuthenticationAnonymous()) {
return "login";
} else {
return "login";
// return "redirect:/list";
}
}
This is the log :
20:02:10.823 [http-nio-8080-exec-10] DEBUG org.springframework.web.servlet.view.JstlView - Forwarding to resource [/WEB-INF/views/login.jsp] in InternalResourceView 'login'
20:02:10.825 [http-nio-8080-exec-10] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
20:02:10.825 [http-nio-8080-exec-10] DEBUG org.springframework.web.servlet.DispatcherServlet - Successfully completed request
20:02:10.825 [http-nio-8080-exec-10] DEBUG org.springframework.security.web.access.ExceptionTranslationFilter - Chain processed normally
20:02:10.825 [http-nio-8080-exec-10] DEBUG org.springframework.security.web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
This is the login.jsp deploying path on tomcat :
C:\me\apache\apache-tomcat-8.0.36\webapps\inbalUI\WEB-INF\classes\WEB-INF\views
But I'm getting HTTP Status 404:
HTTP Status 404 - /inbalUI/WEB-INF/views/login.jsp
type Status report
message /inbalUI/WEB-INF/views/login.jsp
description The requested resource is not available.
Apache Tomcat/8.0.36
Any idea why ?
It seems to me that you use the wrong folder for views.
According to this article https://vitalflux.com/web-application-folder-structure-spring-mvc-web-projects/ this folder should be at:
src/WEB-INF/views/login.jsp
and you probably put it under
src/resources/WEB-INF/views/login.jsp
Which results in WEB-INF/views/login.jsp being put into the classpath (classes/WEB-INF/views/login.jsp)
Related
My Java Spring Authentication and Authorization Server is working.
I want to solve the errors in the requests I send from a client according to the OAuth2 flow. But none of the errors I get are detailed. For example, this request sent to /oauth2/authorize:
https://MY_DOMAIN/authorize?
response_type=code&
client_id=MY_CLIENT_ID&
redirect_uri=MY_CALLBACK_URL&
scope=SCOPE&
state=STATE
Gives the following error after I enter credentials:
My goal is not to resolve the error here, but there are different errors I get like this and I need to see a more informative error message so I can debug them all.
The console also has a non-informative output that goes like this:
...
2022-08-15 15:52:33.739 DEBUG 50827 --- [nio-9000-exec-4] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
2022-08-15 15:52:33.739 DEBUG 50827 --- [nio-9000-exec-4] o.a.c.c.C.[Tomcat].[localhost] : Processing ErrorPage[errorCode=0, location=/error]
2022-08-15 15:52:33.739 DEBUG 50827 --- [nio-9000-exec-4] o.s.security.web.FilterChainProxy : Securing GET /error?protocol=oauth2&response_type=code&access_type&client_id=articles-client&redirect_uri=http%3A%2F%2F127.0.0.1%3A3000%2Flms%2Flogin&scope=openid%20articles.read&state=XqqDv6wx6O&code_challenge_method=plain&code_challenge=e964fe0c4b609ef3cf29658efc6077e7feb591f78c458c2092aa56c9
...
I have written a Pre filter in zuul gateway
#Override
public Object run() throws ZuulException
{
String uniqueID = UUID.randomUUID().toString();
MDC.put("request_id", uniqueID);
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
request.setAttribute("request_id", uniqueID);
//requestContext.set("request_id", uniqueID);
logger.info("request-id generated is => {}", uniqueID);
logger.info("Pre Filter => "+ String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
// MDC.clear();
return null;
}
Zuul gateway logs -> request Id added and appended in logs
2022-08-22 01:57:00.283+0200 [http-nio-8080-exec-6] INFO [] c.h.z.ZuulGatewayApplication$MyFilter - BEFORE
2022-08-22 01:57:00.284+0200 [http-nio-8080-exec-6] INFO [f40d9b07-c33f-4996-bb3a-b16df3ba6436] c.h.z.filter.MDCLoggingPreFilter - request-id generated is => f90447a5-974d-4c38-beba-377addce446c
2022-08-22 01:57:00.284+0200 [http-nio-8080-exec-6] INFO [f40d9b07-c33f-4996-bb3a-b16df3ba6436] c.h.z.filter.MDCLoggingPreFilter - Pre Filter => GET request to http://localhost:8080/home
2022-08-22 01:57:00.285+0200 [http-nio-8080-exec-6] INFO [f40d9b07-c33f-4996-bb3a-b16df3ba6436] c.h.z.f.MDCLoggingPreFilter2 - Pre Filter 2 => GET request to http://localhost:8080/home
2022-08-22 01:57:00.297+0200 [http-nio-8080-exec-6] INFO [f40d9b07-c33f-4996-bb3a-b16df3ba6436] c.h.z.f.MDCLoggingPostFilter - Post Filter => GET request to http://localhost:8080/home
2022-08-22 01:57:00.298+0200 [http-nio-8080-exec-6] INFO [f40d9b07-c33f-4996-bb3a-b16df3ba6436] c.h.z.f.MDCLoggingPostFilter2 - Post Filter 2=> GET request to http://localhost:8080/home
2022-08-22 01:57:00.299+0200 [http-nio-8080-exec-6] INFO [f40d9b07-c33f-4996-bb3a-b16df3ba6436] c.h.z.ZuulGatewayApplication$MyFilter - AFTER
Screenshot
but when the request forwards to client application , there is no request Id
2022-08-22 01:57:00.287+0200 [http-nio-8081-exec-3] INFO [] c.h.z.controller.HomeController - simple get method
Screen Shot For Client microservice
I have a simple Spring MVC Java Application structure:
Spring Version 5.2.3
I am using JSPs as views. (Only have 2 at this point - so super simple).
index.jsp and index2.jsp
On index.jsp I am doing some authentication.
On index2.jsp - this is the view after user has been authenticated.
So index.jsp is rendering fine when I hit the URL in the browser. I do some stuff and then I have a JQuery post call that calls up the Controller and passes it a few things.
Here's the AJAX POST call -
function validateLoginServerSide(eventObj) {
var data = JSON.stringify({
"UIDSignature": eventObj.UIDSignature,
"firstName": eventObj.profile.firstName
});
$.ajax({
url: 'cdc/validate',
headers: {
'Content-Type': 'application/json'
},
method: 'POST',
dataType: 'text',
data: data,
success: function(data){
console.log('succes: ' + data);
},
error: function(jqXHR, status, error) {
console.log('error: ' + error);
}
});
}
Here's the Controller -
#RequestMapping(value = "/validate", method=RequestMethod.POST,
consumes = {MediaType.APPLICATION_JSON_VALUE })
public String validateAuthentication(
#RequestBody CompanyBO signature, ModelMap model) {
model.addAttribute("firstName", signature.getFirstName());
return "index2"; // return internal application page
}
index2 as previously mentioned is a JSP and is located in the following directory in my project:
src/main/webapp
Here's what I don't understand - notice in my post callback in the success function - I print out data.
Well, in the console of my browser I see the contents of my JSP (index2.jsp) perfectly formatted html and even that one binding that resolved to the firstName that I passed into that method, but the browser window itself is still on the original view, index.jsp - so the new jsp is not rendered to the browser window - but it is FOUND, binding resolved, and as you will see below in the logs FORWARDED.
I did some research and I noticed some posts saying that one needs to include this in their POM:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>...</version>
</dependency>
The version is dependent on the version of Tomcat that you are running (so the blogs have stated) --- and the reason for this is because Spring MVC doesn't know how to render JSPs without help. Made sense to me so I tried it - but this didn't work. Still same result.
And finally just to prove I'm not crazy - here's some DEBUG statements from Tomcat (as promised):
22:56:00.676 [http-apr-8080-exec-6] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor - Read "application/json" to [CompanyBO(UIDSignature=1234567, firstName=Alex)]
22:56:00.702 [http-apr-8080-exec-6] DEBUG org.springframework.web.servlet.view.InternalResourceView - View name 'index2', model {org.springframework.validation.BindingResult.companyBO=org.springframework.validation.BeanPropertyBindingResult: 0 errors, firstName=Alex}
22:56:00.702 [http-apr-8080-exec-6] DEBUG org.springframework.web.servlet.view.InternalResourceView - Forwarding to [/index2.jsp]
22:56:00.946 [http-apr-8080-exec-6] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 200 OK
22:56:06.014 [http-apr-8080-exec-8] DEBUG org.springframework.web.servlet.DispatcherServlet - GET "/company/resources/javascript/lib/bootstrap.bundle.js.map", parameters={}
22:56:06.072 [http-apr-8080-exec-8] DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped to ResourceHttpRequestHandler ["/resources/"]
22:56:06.082 [http-apr-8080-exec-9] DEBUG org.springframework.web.servlet.DispatcherServlet - GET "/company/resources/css/lib/bootstrap.min.css.map", parameters={}
22:56:06.084 [http-apr-8080-exec-9] DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped to ResourceHttpRequestHandler ["/resources/"]
22:56:06.186 [http-apr-8080-exec-8] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 200 OK
22:56:06.202 [http-apr-8080-exec-9] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 200 OK
Million dollar question: How is it that the view is found, returned but not rendered?
im trying to to read a value from Google-Cloud storage from my Spring application. I use the Spring Cloud GCP extension to work with Google Cloud Storage.
My Pom.xml for the gcp dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-storage</artifactId>
<version>1.1.2.RELEASE</version>
</dependency>
When i try to read a file from my rest-endpoint i get the exception(at the end of my answer) that somehow that my token could not be refreshed ? Where i can set my clientId or is there something else going on ? I used the code from the sample application which is provided by pivotal and google.
#RestController
public class GCloudStorageController {
#Value("gs://test_files_test/test.txt")
private Resource gcsFile;
#RequestMapping(value = "/cloud", method = RequestMethod.GET)
public String readGcsFile() throws IOException {
return StreamUtils.copyToString(
this.gcsFile.getInputStream(),
Charset.defaultCharset()) + "\n";
}
#RequestMapping(value = "/cloud", method = RequestMethod.POST)
String writeGcs(#RequestBody String data) throws IOException {
try (OutputStream os = ((WritableResource) this.gcsFile).getOutputStream()) {
os.write(data.getBytes());
}
return "file was updated\n";
}
}
2019-08-20 20:27:02.555 DEBUG 12348 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Failed to complete request: com.google.cloud.storage.StorageException: 400 Bad Request
{
"error": "invalid_grant",
"error_description": "Bad Request"
}
2019-08-20 20:27:02.556 DEBUG 12348 --- [nio-8080-exec-1] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#24f1dc0f
2019-08-20 20:27:02.557 DEBUG 12348 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2019-08-20 20:27:02.557 DEBUG 12348 --- [nio-8080-exec-1] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2019-08-20 20:27:02.563 ERROR 12348 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.google.cloud.storage.StorageException: 400 Bad Request
{
"error": "invalid_grant",
"error_description": "Bad Request"
}] with root cause
com.google.api.client.http.HttpResponseException: 400 Bad Request
{
"error": "invalid_grant",
"error_description": "Bad Request"
}
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1094) ~[google-http-client-1.30.1.jar:na]
at com.google.auth.oauth2.UserCredentials.refreshAccessToken(UserCredentials.java:193) ~[google-auth-library-oauth2-http-0.16.1.jar:na]
at com.google.auth.oauth2.OAuth2Credentials.refresh(OAuth2Credentials.java:165) ~[google-auth-library-oauth2-http-0.16.1.jar:na]
at com.google.auth.oauth2.OAuth2Credentials.getRequestMetadata(OAuth2Credentials.java:151) ~[google-auth-library-oauth2-http-0.16.1.jar:na]
at com.google.auth.http.HttpCredentialsAdapter.initialize(HttpCredentialsAdapter.java:96) ~[google-auth-library-oauth2-http-0.16.1.jar:na]
at com.google.cloud.http.HttpTransportOptions$1.initialize(HttpTransportOptions.java:159) ~[google-cloud-core-http-1.79.0.jar:1.79.0]
at com.google.cloud.http.CensusHttpModule$CensusHttpRequestInitializer.initialize(CensusHttpModule.java:109) ~[google-cloud-core-http-1.79.0.jar:1.79.0]
at com.google.api.client.http.HttpRequestFactory.buildRequest(HttpRequestFactory.java:88) ~[google-http-client-1.30.1.jar:na]
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.buildHttpRequest(AbstractGoogleClientRequest.java:430) ~[google-api-client-1.30.1.jar:1.30.1]
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:549) ~[google-api-client-1.30.1.jar:1.30.1]
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:482) ~[google-api-client-1.30.1.jar:1.30.1]
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:599) ~[google-api-client-1.30.1.jar:1.30.1]
at com.google.cloud.storage.spi.v1.HttpStorageRpc.get(HttpStorageRpc.java:433) ~[google-cloud-storage-1.79.0.jar:1.79.0]
at com.google.cloud.storage.StorageImpl$5.call(StorageImpl.java:240) ~[google-cloud-storage-1.79.0.jar:1.79.0]
at com.google.cloud.storage.StorageImpl$5.call(StorageImpl.java:237) ~[google-cloud-storage-1.79.0.jar:1.79.0]
at com.google.api.gax.retrying.DirectRetryingExecutor.submit(DirectRetryingExecutor.java:105) ~[gax-1.46.1.jar:1.46.1]
at com.google.cloud.RetryHelper.run(RetryHelper.java:76) ~[google-cloud-core-1.79.0.jar:1.79.0]
at com.google.cloud.RetryHelper.runWithRetries(RetryHelper.java:50) ~[google-cloud-core-1.79.0.jar:1.79.0]
at com.google.cloud.storage.StorageImpl.get(StorageImpl.java:236) ~[google-cloud-storage-1.79.0.jar:1.79.0]
at com.google.cloud.storage.StorageImpl.get(StorageImpl.java:254) ~[google-cloud-storage-1.79.0.jar:1.79.0]
at org.springframework.cloud.gcp.storage.GoogleStorageResource.getBlob(GoogleStorageResource.java:165) ~[spring-cloud-gcp-storage-1.1.2.RELEASE.jar:1.1.2.RELEASE]
at
Thank you Joe. The resource to implement 'Spring Cloud GCP Core' was never mentioned in the tutorials or i overlooked it.
Somehow another account was connected in my Google Cloud SDK on my console. So i used
gcloud auth application-default login
and logged in the right account. Now it works. Thank you.
This looks like an issue regarding authentication. Did you follow the generic 'Spring Cloud GCP Core' [1] configuration?
Check your application.properties [2] (or other configuration) and make sure it contains at least the following properties:
spring.cloud.gcp.datastore.project-id=XXX
spring.cloud.gcp.datastore.credentials.location=YYY
or choose an other method shown in [1].
[1] https://cloud.spring.io/spring-cloud-static/spring-cloud-gcp/1.1.2.RELEASE/single/spring-cloud-gcp.html#spring-cloud-gcp-core
[2] https://github.com/spring-cloud/spring-cloud-gcp/blob/master/spring-cloud-gcp-samples/spring-cloud-gcp-data-datastore-sample/src/main/resources/application.properties
I am having a issue related to authentication where I am getting logged out of my app when trying to GET from an endpoint that was created from a POST (HTTTP STATUS 201) I see the following errors. The backend is seeing the user as anonymousUser while I am logged in but works fine for another endpoint in the same file :
2018-10-22 11:33:35.251 DEBUG 2124 --- [ XNIO-8 task-23]
c.c.link.aop.logging.LoggingAspect : Enter:
org.springframework.boot.actuate.audit.AuditEventRepository.add() with
argument[s] = [AuditEvent [timestamp=Mon Oct 22 11:33:35 PDT 2018,
principal=anonymousUser, type=AUTHORIZATION_FAILURE,
data={details=org.springframework.security.web.authentication.WebAuthenticationDetails#fffed504:
RemoteIpAddress: 127.0.0.1; SessionId:
_5aP-S8x27gGSIjtbkR6EwrWOD9Yybnd-4M3z0ol, type=org.springframework.security.access.AccessDeniedException,
message=Access is denied}]] 2018-10-22 11:33:35.258 DEBUG 2124 --- [
XNIO-8 task-23] c.c.link.aop.logging.LoggingAspect : Exit:
org.springframework.boot.actuate.audit.AuditEventRepository.add() with
result = null 2018-10-22 11:33:35.343 WARN 2124 --- [ XNIO-8 task-23]
o.z.p.spring.web.advice.AdviceTrait : Unauthorized: Full
authentication is required to access this resource
The same resource (DeliveryResource.java) has an endpoint that works fine
the only difference between both end points is one is /getList (this one is working fine) VS. /getPackingListReport/{number} (this one fails authentication).
The API definitions are shown below:
#GetMapping("/getPackingListReport/{number}")
#Secured(AuthoritiesConstants.USER)
#Timed
public ArrayList<WebOrder> getPackingListReportFromDB(#PathVariable("number") long packingListNbr)
vs.
#GetMapping("/getList")
#Secured(AuthoritiesConstants.USER)
#Timed
public WebOrder getList(#RequestParam(value = "custid") long custid,#RequestParam(value = "pId") long pId) {
I found the problem.
I was using the following for the "/getList" mapping:
// call dao to insert to DB the list and then call the stored proc
URI location = ServletUriComponentsBuilder.fromCurrentContextPath().path("/api/rest/getPackingListReport/{packingListNumber}").buildAndExpand(packingListNumber).toUri();
return ResponseEntity.created(location).build();
to return a created resource URI (HTTP STATUS 201) after a POST. That path contained the incorrect URI starting with , "http://localhost" when jHipster is currently default set to only handle and look for "/api" or in my case i added "/rest/api/*" on the Angular5 side.
I fixed the issue by filtering out any characters before "/api/" after receiving the URL.