Spring Social facebookConnected.jsp - spring

After successful authentication facebook redirects to facebookConnected.jsp. I want it to be redirected to the home page instead. How can it be achieved? I tried doing with controller to redirect but didn't work well.

In ConnectController you got these methods
/**
* Returns the view name of a page to display for a provider when the user is connected to the provider.
* Typically this page would allow the user to disconnect from the provider.
* Defaults to "connect/{providerId}Connected". May be overridden to return a custom view name.
* #param providerId the ID of the provider to display the connection status for.
*/
protected String connectedView(String providerId) {
return getViewPath() + providerId + "Connected";
}
/**
* Returns a RedirectView with the URL to redirect to after a connection is created or deleted.
* Defaults to "/connect/{providerId}" relative to DispatcherServlet's path.
* May be overridden to handle custom redirection needs.
* #param providerId the ID of the provider for which a connection was created or deleted.
* #param request the NativeWebRequest used to access the servlet path when constructing the redirect path.
*/
protected RedirectView connectionStatusRedirect(String providerId, NativeWebRequest request) {
HttpServletRequest servletRequest = request.getNativeRequest(HttpServletRequest.class);
String path = "/connect/" + providerId + getPathExtension(servletRequest);
if (prependServletPath(servletRequest)) {
path = servletRequest.getServletPath() + path;
}
return new RedirectView(path, true);
}
Concretely they say that methods could be overriden to get our specific redirect url. But honestly I don't know how overriding them. I guess you could create a new #Config class that extends it and override #RequestMapping("/connect") too.
If you know some way please write here because I'm on the same situation because I use Spring Webflow and I would like maintaining the flow.
In my case controller /WEB-INF/connect/facebookConnected.xhtml which throw Not Found in ExternalContext as a Resource because I configured my app to look for on folder /WEB-INF/flows.

I had the same problem and I fixed the issue by overriding the ConnectController class
#Controller
#RequestMapping("/connect")
public class CustomController extends ConnectController {
public CustomController(ConnectionFactoryLocator connectionFactoryLocator,
ConnectionRepository connectionRepository) {
super(connectionFactoryLocator, connectionRepository);
}
#Override
protected String connectedView(String providerId) {
return "redirect:/facebook";
}
}
This link has more explanation about how to change the default spring social redirect flow .

Related

redirect to static content using JAX-RS UriBuilder

I have a Jersey Application and I am trying to redirect to a html page which shows the api console when I access "/apiconsole" endpoint as shown below.
/**
* Redirect to API Console
*
* #return API Console
*/
#GET
#Path("/apiconsole")
public Response redirectToApiConsole() {
//redirect path from baseURI to the api console
URI redirectedURL = UriBuilder.fromPath("/api/console/index.html").build();
return Response.seeOther(redirectedURL).build();
}
Is this the same as doing this in Spring?
/**
* Redirect to API Console
*
* #return API Console
*/
#RequestMapping(value = "/apiconsole", method = RequestMethod.GET)
public View redirectToApiConsole() {
return new RedirectView("/api/console/index.html?raml=/api/console/api.raml");
}
You'll have to use Viewable to acheive this and have to update the web.xml to include the servlet filter instead of servlet. I have provided an answer here and here.Hope it helps.

Apache Shiro: How to enforce password change?

I've got a Java EE 7 (JSF, JPA) and CDI based application running, using Shiro for both Authentication and Authorization.
I've got the requirement, that users have to change their password after a certain amount of time (customizable by the application's admin, i.e. 30 days). In our User table we store the information when the password was last set and thus can calculate on Login if it's time to do so.
The plan is to redisplay the login page and represent a different form (change password instead of login). So far so good. However:
How can I enforce the password change and not letting the user navigate to a different page?
Is there a recommended (or even built in) solution?
My idea would be to implement a filter, that checks the session-scoped login object on whether the PW needs to be reset or not.
The hope would be, that this it as simple as creating a new filter, injecting login there and checking the state of the flag - and redirecting the user to the login page as long as flag is true/he does not update his pw.
(We already have a custom cdi aware EnvironmentLoaderListener in place to support our JPA realm.)
The new filter would go behind the last line?
[urls]
/javax.faces.resource/** = anon
/layout.xhtml = anon
/css/** = anon
/login.xhtml = user
/logout.xhtml = logout
/** = user
So we have:
/** = user,pwresetfilter
Suggestions on details as well as on the overall solution are welcome.
You can do with your solution, but probably better to have like that:
You make you own realm
MyRealm extends AuthorizingRealm {
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
}
}
Here in doGetAuthenticationInfo you will check credentials and throw exception if password need to be changed. Feel free to extend realm currently in use.
In your EnvironmentLoaderListener you register your realm
May be in the end you would need to have filter to redirect to correct page, or if you use REST(like Jersey), you could have an exception mapper which will response something to your browser client
I had a similar requirement that was for OTP after authentication and i used normal filter to filter out all requests.
MAke a attribute in use bean like lastPasswordChangedDate or may be a isPasswordChangerequired as you like. and compare it in filter.
My simple otpFliter Code is as follows but you can make your own according to need like jsf, etc.:
/**
* Servlet Filter implementation class OTPFilter
*/
#WebFilter(urlPatterns = {"/*"},initParams={#WebInitParam(name="enabled",value="0")})
public class OTPFilter implements Filter {
/**
* Default constructor.
*/
boolean enabled=true;
public OTPFilter() {
// TODO Auto-generated constructor stub
}
/**
* #see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* #see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
// pass the request along the filter chain
//System.out.println(enabled);
if(enabled){
if(SecurityUtils.getSubject().getPrincipal()!=null){
if(request instanceof HttpServletRequest ){
HttpSession session = ((HttpServletRequest) request).getSession();
LoggedInUser user = (LoggedInUser) session.getAttribute("userinfo");
String url = ((HttpServletRequest) request).getRequestURL().toString();
//System.out.println("url is "+ url);
if( !url.contains("public") && !user.isOTPverified()){
if(user.getOTP() == null)
{
user.setOTP(OTPUtils.generateOTP());
}
//user.setOTPverified(true);
((HttpServletRequest) request).getRequestDispatcher("OTP.jsp").forward(request, response);
return;
}
}
}
}
chain.doFilter(request, response);
}
/**
* #see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
//System.out.println("fConfig.getInitParameter :" + fConfig.getInitParameter("enabled"));
enabled = fConfig.getInitParameter("enabled").equals("1");
}
}

Serving static content alongside thymeleaf templates with Spring Boot

I'm having trouble sonfiguring Spring Boot to use thymeleaf and still serve static content. I have two directories in my resources dir: "/static" and "/templates". According to the Spring Boot documentation, thymeleaf should find thymeleaf templates in the templates directory by default. I am getting a 404 though when I try to use a template.
Relevant code from my Controller:
#RequestMapping("/")
public ModelAndView index() {
return new ModelAndView("index.html");
}
#RequestMapping(value = "/test")
public ModelAndView test() {
return new ModelAndView("test");
}
index.html is in resources/static and test.html is in resources/templates.
index.html works fine, but if you try to open /test in your browser, it throws a 404 saying that the thymeleaf template could not be found.
I really appreciate any help. I'm stumped.
Any pages that are not going through the ThymeleafViewResolver(your /resources/static) need to be removed.
/**
* Configures a {#link ThymeleafViewResolver}
*
* #return the configured {#code ThymeleafViewResolver}
*/
#Bean
public ThymeleafViewResolver thymeleafViewResolver()
{
String[] excludedViews = new String[]{
"/resources/static/*"};
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setOrder(1);
/*
* This is how we get around Thymeleaf view resolvers throwing an error instead of returning
* of null and allowing the next view resolver in the {#see
* DispatcherServlet#resolveViewName(String, Map<String, Object>, Locale,
* HttpServletRequest)} to resolve the view.
*/
resolver.setExcludedViewNames(excludedViews);
return resolver;
}
Have you tried just returning the String name of the template and not ModelAndview?
And have your ModelAttributes annotated as indicated in the documentation?

Grails Spring Security AbstractPreAuthenticatedProcessingFilter redirect

I am trying to do PreAuthentication using Spring Security Grails plugin. I read the pre authentication documentation given below, but could not find anything concrete for my situation
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/preauth.html
In my situation, we have a agent which parses the SAML request and gives a map after successful authentication. Recommendation is to use this jar. Hence, I extended AbstractPreAuthenticatedProcessingFilter and try to do this
#Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
userInfo = agent.readToken(request);
if (!userInfo){
WebUtils.retrieveGrailsWebRequest().getCurrentResponse().sendRedirect(ssoUrl)
}
return userInfo
}
I have placed myFilter under src/groovy and registered this filter in BootStrap
def init = { servletContext ->
SpringSecurityUtils.clientRegisterFilter(
'myFilter', SecurityFilterPosition.PRE_AUTH_FILTER.order)
}
Its getting loaded correctly, but filter is not issuing a redirect. First of all, I wanted to check if this is the right approach and if it is, how to get redirect working.
I have asked the same question in grails user forum
Any help is greatly appreciated.
Update:
Final configuration which worked for me
Wrote MyAuthenticationService which implements AuthenticationUserDetailsService as suggested. You also have to define preAuthenticatedAuthenticationProvider which wraps your custom service
resources.groovy
securityFilter(MySSOAuthFilters){ bean ->
authenticationManager = ref('authenticationManager')
grailsApplication = ref('grailsApplication')
}
customUserDetailsService(MyAuthenticationService)
preAuthenticatedAuthenticationProvider(org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider) {
preAuthenticatedUserDetailsService = ref('customUserDetailsService')
}
I was not able to do <form-login> because in Grails, this is done using
grails.plugins.springsecurity.auth.loginFormUrl config parameter which only accepts relative url.
What I ended up doing is grails.plugins.springsecurity.auth.loginFormUrl = '/login/index'
In LoginController
def index() {
if(springSecurityService.isLoggedIn()){
log.info("User is logged in")
return redirect(controller: 'mycontroller', action: 'list')
}
log.info("user is not logged in...redirect to sso.")
return redirect(url: ssoUrl)
}
Hope this helps
A couple of things I see that need to be changed.
First, do not to send a redirect in the preauth filter just simply return null. The preauth filter is only used to return a subject that your AuthenticationUserDetailsService can use to create the UserDetails object by implementing the method below in your implementation of the AuthenticationUserDetailsService .
public UserDetails loadUserDetails(AbstractAuthenticationToken token) {
return createUserFromSubject((Subject) token.getPrincipal());
}
Second, set the form login page as part of your configuration. This will be used to redirect to if no subject exists.
<form-login login-page="http://url_youwanttoredirect_to_on_auth_req" authentication-failure-url="http://url_youwanttoredirect_to_on_auth_req"/>

Spring 3.0 RESTful Controller Fails on Redirect

I am setting up a simple RESTful controller for a Todo resource with an XML representation. It all works great - until I try to redirect. For example, when I POST a new Todo and attempt to redirect to its new URL (for example /todos/5, I get the following error:
Error 500 Unable to locate object to be marshalled in model: {}
I do know the POST worked because I can manually go to the new URL (/todos/5) and see the newly created resource. Its only when trying to redirect that I get the failure. I know in my example I could just return the newly created Todo object, but I have other cases where a redirect makes sense. The error looks like a marshaling problem, but like I said, it only rears itself when I add redirects to my RESTful methods, and does not occur if manually hitting the URL I am redirecting to.
A snippet of the code:
#Controller
#RequestMapping("/todos")
public class TodoController {
#RequestMapping(value="/{id}", method=GET)
public Todo getTodo(#PathVariable long id) {
return todoRepository.findById(id);
}
#RequestMapping(method=POST)
public String newTodo(#RequestBody Todo todo) {
todoRepository.save(todo); // generates and sets the ID on the todo object
return "redirect:/todos/" + todo.getId();
}
... more methods ...
public void setTodoRepository(TodoRepository todoRepository) {
this.todoRepository = todoRepository;
}
private TodoRepository todoRepository;
}
Can you spot what I am missing? I am suspecting it may have something to do with returning a redirect string - perhaps instead of it triggering a redirect it is actually being passed to the XML marshaling view used by my view resolver (not shown - but typical of all the online examples), and JAXB (the configured OXM tool) doesn't know what to do with it. Just a guess...
Thanks in advance.
This happend because redirect: prefix is handled by InternalResourceViewResolver (actually, by UrlBasedViewResolver). So, if you don't have InternalResourceViewResolver or your request doesn't get into it during view resolution process, redirect is not handled.
To solve it, you can either return a RedirectView from your controller method, or add a custom view resolver for handling redirects:
public class RedirectViewResolver implements ViewResolver, Ordered {
private int order = Integer.MIN_VALUE;
public View resolveViewName(String viewName, Locale arg1) throws Exception {
if (viewName.startsWith(UrlBasedViewResolver.REDIRECT_URL_PREFIX)) {
String redirectUrl = viewName.substring(UrlBasedViewResolver.REDIRECT_URL_PREFIX.length());
return new RedirectView(redirectUrl, true);
}
return null;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
}

Resources