I'm trying to implement JSF authentication with PickeLink 2.6.0 (EAR, Wildfly 8.1.0), as shown in the PicketLink 'picketlink-authentication-jsf' quickstart. I provided an authentication marked with the #PicketLink annotation, but Identity.login() always returns FAILED. This is my JSF form:
<h:form>
<h:panelGrid styleClass="full">
<h:inputText value="#{loginCredentials.userId}" required="true"
pt:placeholder="Username" />
<h:inputSecret value="#{loginCredentials.password}" required="true"
pt:placeholder="Password" />
<h:commandButton value="Login" action="#{loginAction.login()}" />
</h:panelGrid>
</h:form>
This is my LoginAction bean in the WAR module:
import java.util.logging.Logger;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import org.picketlink.Identity;
import org.picketlink.Identity.AuthenticationResult;
import org.picketlink.credential.DefaultLoginCredentials;
#RequestScoped
#Named
public class LoginAction {
#Inject
private Identity identity;
#Inject
private DefaultLoginCredentials credentials;
protected Logger log = Logger.getLogger(this.getClass().getSimpleName());
public void login() {
this.log.info(String.format("%s => %s", this.credentials.getUserId(), this.credentials.getPassword())); // Does get printed!
AuthenticationResult result = this.identity.login();
this.log.info(result.toString());
if (AuthenticationResult.FAILED.equals(result)) {
FacesContext.getCurrentInstance().addMessage(
null,
new FacesMessage(FacesMessage.SEVERITY_ERROR,
"Authentication was unsuccessful. Please check your username and password "
+ "before trying again.", ""));
}
}
}
And my Authenticator in the EJB module:
import java.util.logging.Logger;
import javax.inject.Inject;
import org.picketlink.annotations.PicketLink;
import org.picketlink.authentication.BaseAuthenticator;
import org.picketlink.credential.DefaultLoginCredentials;
#PicketLink
public class Authenticator extends BaseAuthenticator {
#Inject
private DefaultLoginCredentials credentials;
#Inject
private ApplicationAuthenticator applicationAuthenticator;
protected Logger log = Logger.getLogger(this.getClass().getSimpleName());
#Override
public void authenticate() {
this.log.info("authenticate"); // Not printed!
this.log.info(String.format("%s => %s", this.credentials.getUserId(), this.credentials.getPassword()));
ProcessResult auth = this.applicationAuthenticator.authUser(
this.credentials.getUserId(), this.credentials.getPassword());
this.log.info(auth.toString());
if (auth.getResult()) {
this.setStatus(AuthenticationStatus.SUCCESS);
this.log.info(AuthenticationStatus.SUCCESS.toString());
} else {
this.setStatus(AuthenticationStatus.FAILURE);
this.log.info(AuthenticationStatus.FAILURE.toString());
}
}
}
Looks as if my Authenticator is not called at all. This is what I get from the log:
12:25:00,093 INFO [LoginAction] (LoginAction.java:27) defaultuser => defaultpass
12:25:00,105 INFO [idm] (DefaultPartitionManager.java:165) PLIDM001000: Bootstrapping PicketLink IDM Partition Manager
12:25:00,107 INFO [store] (AbstractIdentityStore.java:50) PLIDM001001: Initializing Identity Store [class org.picketlink.idm.file.internal.FileIdentityStore]
12:25:00,110 WARN [file] (FileDataSource.java:173) PLIDM001101: Working directory [C:\Users\JPANGA~1\AppData\Local\Temp\pl-idm] is marked to be always created. All your existing data will be lost.
12:25:00,165 INFO [file] (FileDataSource.java:180) PLIDM001100: Using working directory [C:\Users\JPANGA~1\AppData\Local\Temp\pl-idm].
12:25:00,252 INFO [LoginAction] (LoginAction.java:29) FAILED
The PicketLinks jars are at $EAR_ROOT/lib.
I read the docs at http://docs.jboss.org/picketlink/2/latest/reference/html-single/ and it looks like I'm not missing anything. Why can't I get my Authenticator to work?
After getting more familiar with CDI I realized my silly mistake (the answer wasn't in PLINK docs, but in EE docs). All I needed was to add
#Named
#RequestScoped
to the bean. It still won't work without setting the account after setting the authentication status (I missed that):
this.setStatus(AuthenticationStatus.SUCCESS);
this.setAccount(new User(username)); // <-- don't miss this!
Related
I am attempting to retrieve the credentials for my Google service account with the following code:
package function
import com.amazonaws.services.lambda.runtime.Context
import com.amazonaws.services.lambda.runtime.LambdaLogger
import com.amazonaws.services.lambda.runtime.RequestHandler
import pojo.Request
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential
import com.google.api.services.sqladmin.SQLAdminScopes
import pojo.Response
class GoogleAuth implements RequestHandler<Request, Response> {
private LambdaLogger logger
#Override
Response handleRequest(Request input, Context context) {
logger = context.getLogger()
ClassLoader classLoader = getClass().getClassLoader()
File jsonCredentials = new File(classLoader.getResource("leads-cloud-function-service-account.json").getFile())
FileInputStream fis = new FileInputStream(jsonCredentials)
GoogleCredential credential = GoogleCredential.fromStream(fis).createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN))
credential.getClientAuthentication()
println("Thai test" + credential.getExpirationTimeMilliseconds())
print("This is the credential" + credential.getAccessToken())
return (new Response())
}
}
The information about the milliseconds for expiration and the AccessToken are null. Has anyone ever experienced this?
So I have resolved this myself by adding before the getToken the following command:
credential.refreshToken()
This is not properly documented in google's website but after adding it, this worked perfectly and the results are displayed with actual values.
Some other error I faced was the "com.google.common.io.ByteStreams.exhaust(Ljava/io/InputStream;)J", in order to resolve it I had to correct the dependency I was using to this one:
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.31.1</version>
</dependency>
so, keep on mind that too!
I'm new to JAX-RS and trying to figure out what is happening here:
I have a simple Hello World Jersey REST service running on Glassfish (Eclipse plugin). I can access it successfully from a browser.
Now, I'd like to call it from a Java class (so I can build JUnit tests around it) but I get this error on buildGet() method:
java.lang.SecurityException: Invalid signature file digest for Manifest main attributes
Unless some magic I'm not aware of happens, I'm not packaging my service and/or client in any jar so it's not related to my application jar signature.
Anyone could explain what I'm doing wrong?
Why is the exception triggered on buildGet() metod and not on any method called before?
My main:
package com.test;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
public class HelloTest {
public static void main(String[] args)
{
Client client = ClientBuilder.newClient();
Response response = null;
try {
WebTarget webTarget = client.target("http://localhost:9595/Hello/api/ping");
Invocation helloInvocation = webTarget.request().buildGet();
response = helloInvocation.invoke();
}
catch (Throwable ex) {
System.out.println(ex.getMessage());
}
finally {
response.close();
}
}
}
My service:
package com.api;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
#Path("ping")
public class Hello
{
#GET
#Produces(MediaType.TEXT_HTML)
public String sayHtmlHello()
{
return "<html>" + "<title>" + "Hello" + "</title>"
+ "<body><h1>" + "Hello!!!" + "</body></h1>" + "</html>";
}
}
After struggling on this for a while, it seems that my Maven configuration had issues and some dependencies were not downloaded/built correctly. I restarted a new project, copied my source files and everything started to work as expected.
I am trying to make something with sessions. I have a login form which works well with MySQL database. Now I would like to have a set Session, where it says "Hello B85417" (My username). Everytime I log in I get a this message:
You put in the correct information Hellonull.
Kan anyone see what is wrong here? Best Regards from Mads
index.jsp:
<form action="LoginServlet">
Please enter your username
<input type="text" name="un"/><br>
Please enter your password
<input type="text" name="pw"/>
<input type="submit" value="submit">
</form>
from the login form you are coming to this page:
userLogged.jsp:
<body>
Hello <%= session.getAttribute("currentSessionUser") %>
The servlet who configures the login looks like this:
package ExamplePackage;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, java.io.IOException {
try {
UserBean user = new UserBean();
user.setUserName(request.getParameter("un"));
user.setPassword(request.getParameter("pw"));
user = UserDAO.login(user);
if (user.isValid()) {
HttpSession session = request.getSession(true);
session.setAttribute("currentSessionUser",user);
response.sendRedirect("userLogged.jsp"); //logged-in page
RequestDispatcher rd = request.getRequestDispatcher("PersonalSite.jsp");
rd.include(request,response);
}
else
response.sendRedirect("invalidLogin.jsp"); //error page
}
catch (Throwable theException) {
System.out.println(theException);
}
}
}
It is working fine for me.
You should use
<%= session.getAttribute("currentSessionUser");%>
in the jsp
Request scope will ends in the LoginServlet so it wont available to next jsp. if you call directly userLogged.jsp from index.jsp then it works fine.
OR in the LoggedInServlet
we will have to forward or include the requests to the another jsp rather than redirect.
If you use request Dispatchers for that it will be best as per my knowledge.
RequestDispatcher rd = request.getRequestDispatcher("your_Jsp_name.jsp");
rd.include(request,response);
then only the http request you can get into the another jsp also from your LoginServlet.
OR
you can set these values to the session in the LoginServlet only as follows:
HttpSession session = request.getSession();
session.setAttribute("Your_KEY","Your_Value");
make sure to import javax.servlet.http.HttpSession in the ServletClass.
We had been using GWT-Dispatch to support the RPC calls using command patterns. We now need to move to GWTP since Dispatch has been absorbed into that project. Would seem to be all well and good. The problem is that we are unable to get a DispatchAsync object anymore. In Dispatch, it was extremely simple to get the default implementation:
private final DispatchAsync dispatchAsync = GWT.create(DefaultDispatchAsync.class);
This no longer works. DefaultDispatchAsync is deprecated, and when we use the suggested replacement for it (RpcDispatchAsync) it looks like this:
private final DispatchAsync dispatchAsync = GWT.create(RpcDispatchAsync.class);
we get the following error:
Rebind result 'com.gwtplatform.dispatch.rpc.client.RpcDispatchAsync' has no default (zero argument) constructors.
Does anyone have an idea about how to do this? I know if we rewrite all the pages to use the GWTP MVP pattern that it's available in the Presenter but moving things over to use full GWTP is a long process and if we can't get the RPC calls up and working quickly that will be a problem for the project.
Thanks in advance -- hopefully it's something easy.
DispatchAsync is no longer generated via deferred binding. Thus you can’t use GWT.create to instantiate it.
GWTP Dispatch is making heavy use of GIN/Guice. So I would recommend that you use this dependency injection framework to get GWTP Dispatch work.
Here is an example, which provides easy access to the DispatchAsync (without the need of rewriting all pages to use the GWTP MVP Pattern):
[Note: This example uses gwtp dispatch 1.0.3]
Client:
MyClientModule.java - configure injection-rules for DispatchAsync
import com.google.gwt.inject.client.AbstractGinModule;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.gwtplatform.dispatch.client.DefaultExceptionHandler;
import com.gwtplatform.dispatch.client.DefaultSecurityCookieAccessor;
import com.gwtplatform.dispatch.client.ExceptionHandler;
import com.gwtplatform.dispatch.client.RpcDispatchAsync;
import com.gwtplatform.dispatch.client.actionhandler.ClientActionHandlerRegistry;
import com.gwtplatform.dispatch.client.actionhandler.DefaultClientActionHandlerRegistry;
import com.gwtplatform.dispatch.shared.DispatchAsync;
import com.gwtplatform.dispatch.shared.SecurityCookie;
import com.gwtplatform.dispatch.shared.SecurityCookieAccessor;
public class MyClientModule extends AbstractGinModule {
private static final String COOKIE_NAME = "JSESSIONID";
#Override
protected void configure() {
bindConstant().annotatedWith(SecurityCookie.class).to(COOKIE_NAME);
bind(ExceptionHandler.class).to(DefaultExceptionHandler.class);
bind(SecurityCookieAccessor.class).to(DefaultSecurityCookieAccessor.class);
bind(ClientActionHandlerRegistry.class).to(DefaultClientActionHandlerRegistry.class);
bind(DispatchAsync.class).toProvider(DispatchAsyncProvider.class).in(Singleton.class);
}
public static class DispatchAsyncProvider implements Provider<DispatchAsync> {
private final DispatchAsync fDispatchAsync;
#Inject
public DispatchAsyncProvider(ExceptionHandler eh, SecurityCookieAccessor sca, ClientActionHandlerRegistry cahr) {
this.fDispatchAsync = new RpcDispatchAsync(eh, sca, cahr);
}
#Override
public DispatchAsync get() {
return fDispatchAsync;
}
}
}
MyClientInjector.java - injector provides access to DispatchAsync
import com.google.gwt.inject.client.GinModules;
import com.google.gwt.inject.client.Ginjector;
import com.gwtplatform.dispatch.shared.DispatchAsync;
#GinModules(MyClientModule.class)
public interface MyClientInjector extends Ginjector {
DispatchAsync getDispatchAsync();
}
Server:
MyGuiceServletContextListener.java - create injector for the servlet, which receives the commands and the servermodule, in which the bindings between (clientside) command and (serverside) handler are defined.
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.servlet.GuiceServletContextListener;
public class MyGuiceServletContextListener extends GuiceServletContextListener {
#Override
protected Injector getInjector() {
return Guice.createInjector(new ServerModule(), new DispatchServletModule());
}
}
DispatchServletModule.java - configures the servlet, which receives the commands
import com.google.inject.servlet.ServletModule;
import com.gwtplatform.dispatch.server.guice.DispatchServiceImpl;
import com.gwtplatform.dispatch.server.guice.HttpSessionSecurityCookieFilter;
import com.gwtplatform.dispatch.shared.Action;
import com.gwtplatform.dispatch.shared.SecurityCookie;
public class DispatchServletModule extends ServletModule {
#Override
public void configureServlets() {
bindConstant().annotatedWith(SecurityCookie.class).to("JSESSIONID");
filter("*").through(HttpSessionSecurityCookieFilter.class);
serve("/" + Action.DEFAULT_SERVICE_NAME + "*").with(DispatchServiceImpl.class);
}
}
ServerModule.java - bindings between (clientside) command and (serverside) handler
import com.gwtplatform.dispatch.server.guice.HandlerModule;
public class ServerModule extends HandlerModule {
#Override
protected void configureHandlers() {
bindHandler(YourCommand.class, YourHandler.class);
}
}
web.xml - tell the web-server to use MyGuiceServletContextListener
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
This Guice listener hijacks all further filters and servlets. Extra
filters and servlets have to be configured in your
ServletModule#configureServlets() by calling
serve(String).with(Class<? extends HttpServlet>) and
filter(String).through(Class<? extends Filter)
-->
<listener>
<listener-class>de.gwtpdispatch.server.MyGuiceServletContextListener</listener-class>
</listener>
Usage
Now you can create the injector with deferred binding and get access to the DispatchAsync-instance:
MyClientInjector injector = GWT.create(MyClientInjector.class);
injector.getDispatchAsync().execute(...YourCommand...)
(AND: Don't forget to include the jars of GIN and Guice in your project and add the gin-module to the project's gwt.xml)
I hope this explanation is detailed enough. Happy coding :)
I have exposed an api provided by a jetty server to a front-end application. I want to make sure that only the front-end application (from a certain domain) has access to that api - any other requests should be unauthorised.
What's the best best way of implementing this security feature?
Update: I have set up a CrossOriginFilter - however, I can still access the api via basic GET request from my browser.
Thanks!
Use the IPAccessHandler to setup whitelists and blacklists.
Example: this will allow 127.0.0.* and 192.168.1.* to access everything.
But 192.168.1.132 cannot access /home/* content.
package jetty.demo;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.IPAccessHandler;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
public class IpAccessExample
{
public static void main(String[] args)
{
System.setProperty("org.eclipse.jetty.servlet.LEVEL","DEBUG");
System.setProperty("org.eclipse.jetty.server.handler.LEVEL","DEBUG");
Server server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(8080);
server.addConnector(connector);
// Setup IPAccessHandler
IPAccessHandler ipaccess = new IPAccessHandler();
ipaccess.addWhite("127.0.0.0-255|/*");
ipaccess.addWhite("192.168.1.1-255|/*");
ipaccess.addBlack("192.168.1.132|/home/*");
server.setHandler(ipaccess);
// Setup the basic application "context" for this application at "/"
// This is also known as the handler tree (in jetty speak)
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
// make context a subordinate of ipaccess
ipaccess.setHandler(context);
// The filesystem paths we will map
String homePath = System.getProperty("user.home");
String pwdPath = System.getProperty("user.dir");
// Fist, add special pathspec of "/home/" content mapped to the homePath
ServletHolder holderHome = new ServletHolder("static-home", DefaultServlet.class);
holderHome.setInitParameter("resourceBase",homePath);
holderHome.setInitParameter("dirAllowed","true");
holderHome.setInitParameter("pathInfoOnly","true");
context.addServlet(holderHome,"/home/*");
// Lastly, the default servlet for root content
// It is important that this is last.
ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class);
holderPwd.setInitParameter("resourceBase",pwdPath);
holderPwd.setInitParameter("dirAllowed","true");
context.addServlet(holderPwd,"/");
try
{
server.start();
server.join();
}
catch (Throwable t)
{
t.printStackTrace(System.err);
}
}
}
Or alternatively, write your own Handler to filter based on some other arbitrary rule.
Such as looking for a required request header, something that your specific front-end application provides, but a browser would not.
package jetty.demo;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.HandlerWrapper;
public class BanBrowserHandler extends HandlerWrapper
{
#Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
String xfe = request.getHeader("X-FrontEnd");
if ((xfe == null) || (!xfe.startsWith("MagicApp-")))
{
// not your front-end
response.sendError(HttpStatus.FORBIDDEN_403);
baseRequest.setHandled(true);
return;
}
getHandler().handle(target,baseRequest,request,response);
}
}
The class IPAccessHandler is deprecated. The InetAccessHandler is recommended.
org.eclipse.jetty.server.Server server = ...;
InetAccessHandler ipaccess = new InetAccessHandler();
ipaccess.include(clientIP);
ipaccess.setHandler(server.getHandler());
server.setHandler(ipaccess);