I am trying to create a RestEasy client for services host in JBPM server. The service url is always redirecting to a form based login screen which expects j_username and j_password.
I need to login to the service and also have to store the cookies to avoid authentication everytime. Please suggest the best implementation to achieve this.
Now all the service calls ends up in returning the login html page.
I tried some of the solutions posted here, but not works in my scenario.
RESTEasy client framework authentication credentials
RestEasy Client Authentication and HTTP Put with Marshalling
First, write an authetication servlet (where you can intercept the login credentials and store them to your cookie):
#WebServlet(urlPatterns = {"/security_check"})
public class AuthenticationServlet extends HttpServlet
{
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throwsServletException, IOException
{
request.login(userName, userPassword);
StoreInCookieMethod(request.getUserPrincipal().getName(), userPassword);
response.sendRedirect(request.getContextPath() + "/protectedResourceUrlPattern/");
}
}
in the login_form, map the action to the servlet URL
eg:
<form method="post" action="security_check">
for all other requests other than login, define a url pattern(eg protectedResourceUrlPattern) and autheticate using the credentials from cookie
Related
I have an implementation of AuthenticationSuccessHandler that catches the request after user is successfully logged in. So when processing is finished inside a handler, I want to redirect a user to the page that he first desired to go, before he was redirected to the login page, and not to some hardcoded page. Is this possible?
This is how my handler implementation looks like:
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
Util.setUserdata(userBean, authentication, request);
proceed(request, response, authentication);
}
To explain the problem more clearly, a short example:
User wants to land to a page app/test/page.html
He gets redirected login page and logs in successfully
Handler method gets invoked and I do some logic after which I want to redirect him back to app/test/page.html, but I don't know how to access the URL he wanted to land on before redirection to login page.
Spring security's ExceptionTranslationFilter actually stores the request in session before redirecting to login.
ExceptionTranslationFilter.java
And then it has SavedRequestAwareAuthenticationSuccessHandler which is a AuthenticationSuccessHandler that retrieves and forwards to it.
SavedRequestAwareAuthenticationSuccessHandler.java
You don't need to use that SavedRequestAwareAuthenticationSuccessHandler directly if you have some customization. You can get the previous url directly from session like session.getAttribute(""SPRING_SECURITY_SAVED_REQUEST") as well and it has url and method etc so you can do the redirect yourself. You will have to cast it to SavedRequest before you can the url etc if you are going this route
I'm working on an application with Spring Boot 5 and OIDC. I've configured OIDC with Google and it works fine. I'm redirected to login at Google and then it redirects me to the app creating a new session. Now I'm trying to use Google One-Tap. It works fine as well. When user clicks on the one-tap's modal to continue with his Google identity I receive a POST with the id_token. What I want to do is to create a Spring session from this POST as it is created when user is logged by OIDC.
I think the right way is to create a Filter extending AbstractAuthenticationProcessingFilter. I've found some references here and here but I don't have the access_token when receiving the one-tap POST:
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
...
OAuth2AuthenticationToken oauth2Authentication = new OAuth2AuthenticationToken(
authenticationResult.getPrincipal(),
authenticationResult.getAuthorities(),
authenticationResult.getClientRegistration().getRegistrationId());
oauth2Authentication.setDetails(authenticationDetails);
OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(
authenticationResult.getClientRegistration(),
oauth2Authentication.getName(),
authenticationResult.getAccessToken(),
authenticationResult.getRefreshToken());
this.authorizedClientRepository.saveAuthorizedClient(authorizedClient, oauth2Authentication, request, response);
return oauth2Authentication;
}
Has anyone tried to do it before ?
I've finally found a solution. I've shared the code here. Hope it helps to anyone dealing with the same issue.
My question is simple - how to implement login-logout in servlet jsp?
Following is the use case...
I have a users table in DB with email,username and password
I have a mapped bean object - User in java having email,username,password properties
Simply I want to login by validating email and password BUT
Once I login and then logout, when I click on back button, it should not retain the session.
It should not give any warning BUT simply should ask for login
If I copy-paste restricted resource's link, it should ask for login
What all solutions I've gone through...
Some say to implement tomcat security using roles and bla bla... BUt I think I should not set username, passwords in some tomcat config file. Bcz the details are in DB table
Some ask to implement no-cache, pragma bla bla... but never work
Back button disable is foolish thing
**
What Help I am expecting from you guys ...?
**
Is there any third-party API available to do this?
How things are implemented in production ready applications ?
Should I use JAAS, or any other security process for exactly above mentioned scenario OR WHAT
Please give me some hint or solution how I should proceed implementing production ready login-logout in servlet-jsp
I've searched on internet but end up with simple Login examples or tomcat security roles etc. No one gives the actual solution. ANd please don't say that this question is NOT RELATED TO this FORUM.
Thanks
This happens because browser caches the web pages that are being loaded,you can prevent it by using filters and telling browser not to cache the web pages like below.
doFilter method of Filter
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
HttpSession session = request.getSession(false);//don't create if session doesn't exist.
if (session==null || session.getAttribute("username") == null) {
RequestDispatcher rd=request.getRequestDispatcher("login");//dispatch it to your desired page i.e login page
rd.forward(request, response);
} else {
chain.doFilter(req, res);
}
}
You should configure this filter inside web.xml or using Annotations for which url-patterns you want to filter.refer documentation for more details.
If you're using Tomcat then a good place to start is Tomcat Standard Realm Implementations.
It's important to remember that normal Java EE security authenticates users and authorises them using roles - even if you only have the one.
Once you have done that you can implement Logout by invoking a servlet which calls HttpServletRequest.logout() and then invalidates the HttpSession:
request.logout();
request.getSession().invalidate();
and then:
response.sendRedirect("some protected page");
which should resolve your back button problem and land back on the login page.
I need to redirect the url according to the username in the url.
Let say, url is of the form of
get http://192.168.2.0/user1/app/node-id/info
then,
it should redirect this url to different server like,
get http://192.168.2.1/app/node-id/info
The client should be unaware of the fact, it is being redirected.
He/She should see the same url, but the response should come from the redirected url in Json or html format.
Which we can perform via request forwarding.
Every where I am able to see the solution servlet way.
What is the best way to do it spring way?
Java servlets have redirect and forward methods. Difference between them are explained on here and you can use them as below; redirect changes the url but forward processes the request internal.
If you want to redirect users to a remote url check this Q&A and maybe to redirect without changing browser's address, the easy way is reading it with url and writing it to response on servlet
private void redirect(ResponsePage aDestinationPage, HttpServletResponse aResponse) throws IOException {
String urlWithSessionID = aResponse.encodeRedirectURL(aDestinationPage.toString());
aResponse.sendRedirect( urlWithSessionID );
}
private void forward(ResponsePage aResponsePage, HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletException, IOException {
RequestDispatcher dispatcher = aRequest.getRequestDispatcher(aResponsePage.toString());
dispatcher.forward(aRequest, aResponse);
}
In addition for usernames on url addresses, you can use filters and redirect them as your wish. For using spring with filter please check here and here
Spring social and security experts,
I have the following use case:
User requests a specific URL like http://www.foobar.com/foo/1001
Anonymous user can see this page but cannot post a comment in this page. Comment posting part is secured by Spring security.
User clicks login. It pops up a login window or redirect it to login page.
The user chooses to sign in with Facebook ID.
After user signed in using FB, it redirects the user to http://www.foobar.com/foo/1001 with authorization.
I was wondering how I can do that using Spring Social. Thanks a lot!!
Have you actually tried it to see if it works? Spring security does this automatically.
If you are an anonymous user and attempt to access a resource that requires a certain permission, spring security will store the attempted URL and redirect you to the login page. After successful login it fetches the attempted URL back and redirects you there.
I have only managed to do this by copy/pasting code which spring security uses to do this job.
CAVEAT: I am using ProviderSignInController to provision accounts and sign in.
ProviderSignInController permits the use of a SignInAdapter to manually login local user account based on the SocialConnection
In the signIn method:
public String signIn(String userId, Connection<?> connection, NativeWebRequest request)
I have the following code:
HttpServletRequest req = (HttpServletRequest)request.getNativeRequest();
HttpServletResponse resp = (HttpServletResponse)request.getNativeResponse();
RequestCache rc = new HttpSessionRequestCache();
SavedRequest savedRequest = rc.getRequest(req, resp);
String targetUrl = savedRequest.getRedirectUrl();
if(targetUrl != null){
log.info("Redirecting to DefaultSavedRequest Url: " + targetUrl);
new DefaultRedirectStrategy().sendRedirect(req, resp, targetUrl);
hasSentRedirect = true;
}
I had to dig through the code of SavedRequestAwareAuthenticationSuccessHandler to see how this works as part of spring security.
I am disappointed that ProviderSignInController isn't really linked to Spring Security at all. And so we must hack our way around to get the same functionality.
I have also found that login events aren't posted either.
I have asked about this recently: Should I use both SocialAuthenticationFilter and ProviderSignInController together