I inherited some Java code that does Single Server Sign for the BMC Remedy AR System. The code works by pulling the Kerberos ticket from the headers and then validates it by making calls to domain controllers.
The Remedy server makes a call to a method:
public UserCredentials getAuthenticatedCredentials(HttpServletRequest request,HttpServletResponse response) throws IOException
Within that method the Authorization header is extracted. For both IE and Chrome this works correctly.
The next step is to get the users timezone using a custom JSP page which is called via the following:
RequestDispatcher reqDisp = request.getRequestDispatcher(Login.CUSTOM_TIMEZONE_URL);
if (reqDisp != null) {
try {
reqDisp.forward(request, response);
} catch (Exception e) {
System.out.println("Error");
e.printStackTrace();
}
}
This is working correctly in IE8 and IE11 but not in Chrome. For IE the header still contains the Authorization values after the time zone call so I can perform the Kerberos check but for Chrome the Authorization headers are missing.
(I can post the complete headers if that would help)
Thank you
Related
Is there a way to set a cookie for a website I'm trying to redirect to? I'm trying to use Spring redirect to achieve this but I think I'm doing something work (or this is not possible at all)
Here's the method I have tried to use:
#GetMapping("/redirect")
public void redirect(HttpServletResponse response) throws IOException {
Cookie testCookie = new Cookie("test-cookie", "blah");
testCookie.setDomain("something.com");
testCookie.setPath("/");
response.addCookie(testCookie);
response.sendRedirect("https://something.com/test.html");
}
I can see the "set-cookie" header but no actual cookie seems to be set in my browser.
M
Encountered same problem. My case was to pass redirect from backend to frontend with attached cookies. Within one main domain. There's no success with code
cookie.path = "/"
cookie.domain = "domain.com"
cookie.maxAge = 60
cookie.isHttpOnly = false
response.addCookie(cookie)
But everything run when I changed to
response.setHeader("Set-Cookie", "customCookie=value; Path=/; Max-Age=60; Domain=domain.com")
Important: cross-domain cookie passing will be blocked by browser
I am working on a platform made in VAADIN. If you want to see it is www.wikire.it.
In this home page, to login, you have to click on "Accedi" and then compile textfields into the modal form that appears.
The platform has also another application (different from that mentioned before) that works as backoffice.
The purpose is to make a button in the backoffice that logges into the site with some credentials(is not important how to get it).
I am new in this platform, I have some ideas but i don't know what to do (as workflow) :
- Rest Services
- Web services from the site
How can I satisfy my purpose ?
Sorry if is a generic question, but I need it for my work and i don't know what to do for first.
One way you can do this without changing much in your existing site is to:
use the Apache's HttpClient library to launch, triggered by some user action like a button or link click in your backoffice app, a (POST) request with the necessary parameters (username, password, eventual hidden fields) towards your site's login address (I believe in your case it's http://www.wikire.it/logon)
upon a successful login, the site will (probably) send back to your HttpClient instance at least one cookie used for authentication -- get a hold of it :) (in the example I've provided -- see below -- I am assuming this cookie is named JSESSION, the usual case for Java apps creating a user session; if your site is done using a different technology like PHP, etc. make sure you find out how the session / authentication cookie looks like for that technology)
set an identical cookie (for the site's domain, wikire.it and / as path) in your response to the request that had been done in the backoffice (Remember: A. the auth cookie you receive back from the site is set / present for the HttpClient instance for the moment, not for the actual client, which is your browser! and B. handling a Vaadin event, within a listener, eventually implies a response that will be sent back to your browser
to finish handling the user click, ask the Vaadin Page to execute a window.open('http://www.wikire.it/') JavaScript call (i.e. passing your target site's address and, maybe, '_blank' as a second parameter to force opening the page in a new window / tab; this might get blocked though by a browser that wouldn't allow opening popups so... take care)
That should do it. Note that logging into a site is completely independent of Vaadin -- you just have to find a way to set the cookie for the browser and make it execute that last JavaScript call.
I've created 2 sample projects here: https://github.com/octavian-nita/so/tree/master/so-42927030-vaadin-login-to-site-button. site is a very basic java / jsp app protected by a login page (the user name you can use to login is Johnny, the password doesn't matter) to serve as target site to login to. backoffice is a tiny Vaadin app with a button you can click to login to site.
For your convenience, I'm highlighting the relevant bits of code below.
Adding a Maven Dependency on HttpClient
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
Creating a Routine That Logs Into a Site and Returns the Auth Cookie
This implies you know the path used for the login action (usually what's specified in the login form).
private Cookie login(URI targetUri, String loginPath, Map<String, String> params) throws IOException {
requireNonNull(targetUri);
requireNonNull(loginPath);
// Keep track of cookies we might receive in an HttpClient:
final CookieStore cookies = new BasicCookieStore();
// Build and work with an (AutoCloseable) HttpClient that uses the cookie store:
try (CloseableHttpClient client = HttpClients.custom().setDefaultCookieStore(cookies).build()) {
// Prepare (login) request parameters:
List<NameValuePair> reqParams = new ArrayList<>();
if (params != null) {
for (Map.Entry<String, String> entry : params.entrySet()) {
reqParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
}
// Execute the login (POST) request with the given parameters:
HttpPost post = new HttpPost(targetUri + loginPath);
post.setEntity(new UrlEncodedFormEntity(reqParams));
CloseableHttpResponse response = client.execute(post);
// Eventually, check the response to see if successful
response.close();
// Look for a JSESSIONID-named cookie stored in the HttpClient and return it to be used by calling code:
for (org.apache.http.cookie.Cookie cookie : cookies.getCookies()) {
if ("JSESSIONID".equalsIgnoreCase(cookie.getName())) {
String domain = targetUri.getHost();
if (domain.startsWith("www.")) {
domain = domain.substring(4);
}
Cookie authCookie = new Cookie(cookie.getName(), cookie.getValue());
authCookie.setDomain(domain);
authCookie.setPath("/");
// Eventually, set expiry (to allow longer login) and other things...
return authCookie;
}
}
return null; // some sort of error?
}
}
Setting the Auth Cookie in the Browser and Opening the Site, in Vaadin
#Title("Backoffice for SO Question #42927030")
public class MainUI extends UI {
private Cookie login(URI targetUri, String loginPath, Map<String, String> params) throws IOException {
// ...
}
#Override
protected void init(VaadinRequest vaadinRequest) {
setContent(new VerticalLayout(new Button("Log into site...", event -> {
try {
URI targetUri = new URI("http://localhost:8080");
Map<String, String> params = new HashMap<>();
params.put("username", "Johnny");
params.put("password", "incorrect :)");
// Eventual hidden fields, etc.
// params.put("...", "...");
Cookie targetAuthCookie = login(targetUri, "/log-me-in", params);
// We're not ready just yet: we still need to 'transfer' the cookie
// the HTTP client received to the current browser:
VaadinService.getCurrentResponse().addCookie(targetAuthCookie);
// Upon responding to the Vaadin 'click' request, open the target URL (eventually in a new page / tab):
Page.getCurrent().getJavaScript().execute("window.open('" + targetUri + "');");
} catch (Exception ex) {
ex.printStackTrace();
}
})));
}
#WebServlet(urlPatterns = "/*", name = "MainUIServlet", asyncSupported = true)
#VaadinServletConfiguration(ui = MainUI.class, productionMode = false)
public static class MainUIServlet extends VaadinServlet {}
}
Let us know how this goes for you...
I am using the following code to update a confluence page:
public void publish() throws IOException {
XWikiXmlRpcClient rpc = new XWikiXmlRpcClient(CONFLUENCE_URI);
try {
rpc.login(USER_NAME, PASSWORD);
//The info macro would get rendered an info box in the Page
Page page = new Page();
page.setSpace("ATF");
page.setTitle("New Page");
page.setContent("New Page Created \\\\ {{info}}This is XMLRPC Test{{/info}}");
page.setParentId("demo UTF Home");
rpc.storePage(page);
} catch (XmlRpcException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
When I try to run the program, I get the following exception:
org.apache.xmlrpc.client.XmlRpcClientException: Failed to parse server's response: Expected methodResponse element, got html
This looks like a bug in Apache xml-rpc client going by this JIRA:
https://issues.apache.org/jira/browse/XMLRPC-159
It says it was fixed in 3.1.2 of the library, I am using 3.1.3.
Anyone seen this before?
Maybe the server really returned HTML; sometimes it simply returns a 200 because something is there that always produces HTML. In that case the bugfix in the XMLRPC-library you have linked to does not apply.
To check for this possibility, you can look into the server access logs for the url of the request and the status code (should be a 200); with this information you can replay the request e.g. in a browser or command line client like wget or curl, and see what is really returned as response.
I am trying to automate downloading text data from a website. Before I can access the website's data,I have to input my username and password. The code I use to scrape the text is listed below. The problem is I can't figure out how to login to the page and redirect to the location of the data. I have tried login in through my browser and then running my code through eclipse but I just end up getting data from the log in screen. I can retireve data from webistes just fine provided I don't have to go through a login.
static public void printPageA(String urlString){
try {
// Create a URL for the desired page
URL url = new URL(urlString);
// Read all the text returned by the server
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
while ((str = in.readLine()) != null) {
System.out.println(str);
// str is one line of text; readLine() strips the newline character(s)
}
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
}
I would suggest you to use Apache HTTP Client library. It will make it easier to make HTTP requests and it takes care of things like cookies. The site probably uses cookies for keeping information about your session, so you need to:
Make the same request as when you submit the login form. This is probably a POST request with parameters such as username and password. You can see it in a network monitor of your browser (developer tools).
Read the response. It will probably contain a Set-Cookie header containing an ID of your session. You have to send this cookie along with all your subsequent requests, otherwise you will get to the login page. If you use the HTTP Client library, it will take care of it, no need to mess with it in your code.
Create a request to any page of the web site that requires authentication.
There are different methods to create cookies in HttpClient, I am confused which one is the best.
I need to create,retrieve and modify cookies.
For example , I can use the following code to see a list of cookies and modify them but how to create them ?
Is this a proper method for retrieving them? I need them to be accessible in all classes.
In addition methods that I have found usually require httpresponse, httprequest objects to send the cookie to browser, but how about if I do not want to use them?
Code
import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
public class GetCookiePrintAndSetValue {
public static void main(String args[]) throws Exception {
HttpClient client = new HttpClient();
client.getParams().setParameter("http.useragent", "My Browser");
GetMethod method = new GetMethod("http://localhost:8080/");
try{
client.executeMethod(method);
Cookie[] cookies = client.getState().getCookies();
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
System.err.println(
"Cookie: " + cookie.getName() +
", Value: " + cookie.getValue() +
", IsPersistent?: " + cookie.isPersistent() +
", Expiry Date: " + cookie.getExpiryDate() +
", Comment: " + cookie.getComment());
cookie.setValue("My own value");
}
client.executeMethod(method);
} catch(Exception e) {
System.err.println(e);
} finally {
method.releaseConnection();
}
}
}
AND I've tried to create a cookie using following code but it does not
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
....
public String execute() {
try{
System.err.println("Creating the cookie");
HttpClient httpclient = new HttpClient();
httpclient.getParams().setParameter("http.useragent", "My Browser");
GetMethod method = new GetMethod("http://localhost:8080/");
httpclient.executeMethod(method);
org.apache.commons.httpclient.Cookie cookie = new
org.apache.commons.httpclient.Cookie();
cookie.setPath("/");
cookie.setName("Tim");
cookie.setValue("Tim");
cookie.setDomain("localhost");
httpclient.getState().addCookie(cookie);
httpclient.executeMethod(method);
System.err.println("cookie");
}catch(Exception e){
e.printStackTrace();
}
Output is as following but no cookie will be created.
SEVERE: Creating the cookie
SEVERE: cookie
Scenario
1)User has access to a form to search for products (example.com/Search/Products)
2)User fills up the form and submit it to class Search
3)Form will be submitted to Search class
4)Method Products of Search class returns and shows the description of product
(example.com/Search/Products)
5)User clicks on "more" button for more description about product
6)Request will be sent to Product class (example.com/Product/Description?id=4)
7)User clicks on "add to cookie" button to add the product id to the cookie
Product class is subclasse of another class. So it can not extend any more class.
In the second example, you are creating a new client-side cookie (i.e. you are impersonating a browser and are sending the cookie to the server).
This means that you need to provide all the relevant information, so that the client can decide whether to send the cookie to the server or not.
In your code you correctly set the path,name and value, but the domain information is missing.
org.apache.commons.httpclient.Cookie cookie
= new org.apache.commons.httpclient.Cookie();
cookie.setDomain("localhost");
cookie.setPath("/");
cookie.setName("Tim");
cookie.setValue("Tim");
This works if what you are trying to achieve is to send a cookie to an http server.
Your second example, though, spans from an execute method, an since you are hinting at struts2 in your tag, maybe the class containing it is meant to be a struts2 Action.
If this is the case, what you are trying to achieve is to send a new cookie to a browser.
The first approach is to get hold of a HttpServletResponse as in:
So your Action must look like:
public class SetCookieAction
implements ServletResponseAware // needed to access the
// HttpServletResponse
{
HttpServletResponse servletResponse;
public String execute() {
// Create the cookie
Cookie div = new Cookie("Tim", "Tim");
div.setMaxAge(3600); // lasts one hour
servletResponse.addCookie(div);
return "success";
}
public void setServletResponse(HttpServletResponse servletResponse) {
this.servletResponse = servletResponse;
}
}
Another approach (without HttpServletResponse) could be obtained using the CookieProviderInterceptor.
Enable it in struts.xml
<action ... >
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="cookieProvider"/>
...
</action>
then implement CookieProvider as:
public class SetCookieAction
implements CookieProvider // needed to provide the coookies
{
Set<javax.servlet.http.Cookie> cookies=
new HashSet<javax.servlet.http.Cookie>();
public Set<javax.servlet.http.Cookie> getCookies()
{
return cookies;
}
public String execute() {
// Create the cookie
javax.servlet.http.Cookie div =
new javax.servlet.http.Cookie("Tim", "Tim");
div.setMaxAge(3600); // lasts one hour
cookies.put(cookie)
return "success";
}
}
(credits to #RomanC for pointing out this solution)
If you subsequently need to read it you have two options:
implement ServletRequestAware in your Action and read the cookies from the HttpServletRequest
introduce a CookieInterceptor and implement CookiesAware in your Action, the method setCookieMap allows to read the cookies.
Here you can find some relevant info:
Using cookies with Struts 2 and Struts
First of all you propably do not want to use HttpClient, which is a client (e.g. emulates a browser) and not a server (which can create cookies, that the user's browser will store).
That said, I'm first explaining what happens in your first code example:
You send a GET request to a server
The server sends you some cookies alongside it's response (the content)
You modify the cookies in your HttpClient instance
You send those cookies back to the server
What the server does with your changed cookies entirely depends on what that server is programmed to do
At the next request the server might send those changed cookies back to you or not, which as I allraedy said depends on what it is programmed to do.
As for you second example:
You create a cookie
You set some information on the cookie
You send the cookie to the server (inside your GET request)
The server now does with your cookie what it is programmed to do with it. Propably the server ignores your cookie (e.g. does not send it back to you).
On the other hand what you propably want to do is write a web application (e.g. the server side), that creates the cookie and changes it depending on the client's input (the browser).
For that you can use the Servlet API. Something along the lines:
javax.servlet.http.Cookie cookie = new
javax.servlet.http.Cookie("your cookie's name", "your cookie's value");
//response has type javax.servlet.http.HttpServletResponse
response.addCookie(cookie);
Creating a web application is way out of scope of a simple stackoverflow answer, but there are many good tutorials out there in the web.
There is no way around creating a web application if the user should use a browser to see your products. There are just different ways to create one, different frameworks. The servlet API (e.g. HttpServletResponse and HttpServletResponse) is the most basic one.
I'd say it (the servlet API) is also the easiest one you can find to solve this exact problem with java, even though it is not exactly easy to get started with web applications at all.