steam OpenID authentication without a callback-URL - java

I am trying how to add a steam logging to my java application .I have try out few OpenID libraries in http://openid.net/developers/libraries, And this is for JOpenID ,
Eg - >
OpenIdManager manager = new OpenIdManager();
manager.setTimeOut(10000);
Endpoint endpoint = manager.lookupEndpoint("http://steamcommunity.com/openid");
System.out.println(endpoint);
Association association = manager.lookupAssociation(endpoint);
System.out.println(association);
String url = manager.getAuthenticationUrl(endpoint, association);
System.out.println("Copy the authentication URL in browser:\n" + url);
System.out.println("After successfully sign on in browser, enter the URL of address bar in browser:");
String ret = url;
HttpServletRequest request = createRequest(ret);
Authentication authentication = manager.getAuthentication(request, association.getRawMacKey(), endpoint.getAlias());
System.out.println(authentication);
Because i am not trying this for web app and I Dont have a callback-URL to use , i have use "easymock"
public HttpServletRequest createRequest(String url) throws UnsupportedEncodingException {
int pos = url.indexOf('?');
if (pos==(-1))
throw new IllegalArgumentException("Bad url.");
String query = url.substring(pos + 1);
String[] params = query.split("[\\&]+");
final Map<String, String> map = new HashMap<String, String>();
for (String param : params) {
pos = param.indexOf('=');
if (pos==(-1))
throw new IllegalArgumentException("Bad url.");
String key = param.substring(0, pos);
String value = param.substring(pos + 1);
map.put(key, URLDecoder.decode(value, "UTF-8"));
}
return (HttpServletRequest) Proxy.newProxyInstance(
Main.class.getClassLoader(),
new Class[] { HttpServletRequest.class },
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("getParameter"))
return map.get((String)args[0]);
throw new UnsupportedOperationException(method.getName());
}
}
);
}
But I am getting a error saying ,
java.lang.IllegalArgumentException: interface javax.servlet.http.HttpServletRequest is not visible from class loader
at java.lang.reflect.Proxy.getProxyClass0(Proxy.java:487)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:722)
and i have ALSO try as the code like in
https://gist.github.com/FernFerret/7692878 too (for Openid4java and spark) but got error when creating Route like in link saying there is no 'Route(String)'
get(new Route("/") {
So how can i Make OpenID authentication with out a Redirect URL ?
Can any one can guide me for a java OpenID Authentication for Steam using "any" OpenID code ?
I just need That returned value( like-> http//steamcommunity.com/openid/id/76561197960435530") informed in
http://steamcommunity.com/dev/
Which is the only value that returns .
Many Thanks For Any inputs !!

Related

How to create a token for a role in dropwizard?

I am trying to create a login token for a user. Let's call that user "manager". There are already existing tokens for different roles. The manager role is a role such that the manager can also be an agent. Thus, a manager should be able to login on two different platforms - Mobile and Web and the manager should not be logged out from either of the platforms.
Here is what the profile service looks like.
public class ProfileService {
private String baseUrl;
private ObjectMapper objectMapper;
public ProfileService(String baseUrl) {
this.baseUrl = baseUrl;
objectMapper = new ObjectMapper();
}
public ProfileDTO fetchUserProfile(String profileId){
Client client = ClientBuilder.newClient();
log.info("This is the base url {}", baseUrl);
Map response = client.target(baseUrl + "/api/v1/users/" + profileId).request().get(Map.class);
Object data = response.get("data");
Map dataMap = this.objectMapper.convertValue(data, Map.class);
Map roleGroup = this.objectMapper.convertValue(dataMap.get("roleGroup"), Map.class);
List roleObjs = this.objectMapper.convertValue(dataMap.get("roles"), List.class);
String userType = dataMap.get("userType").toString();
String roleGroupName = (Objects.isNull(roleGroup)) ? userType : roleGroup.get("name").toString();
List<String> roles = new ArrayList<>();
if (Objects.nonNull(roleObjs)) {
for (Object entry : roleObjs) {
Map role = this.objectMapper.convertValue(entry, Map.class);
roles.add(role.get("name").toString().toUpperCase(Locale.ROOT));
}
}
return new ProfileDTO(dataMap.get("id").toString(), dataMap.get("email").toString(),
dataMap.get("firstName").toString(), roleGroupName, userType,
roles, (Boolean) dataMap.get("enabled"), (Boolean) dataMap.get("verified"));
}
}
Here is the existing service that is not giving me the desired results.
private void verify(ProfileDTO profile, Types.Platform platform) throws AuthenticationException {
if (!profile.isEnabled() || profile.getUserType() == null) {
throw new AuthenticationException("Unauthorized!");
}
switch (platform) {
case WEB:
if(!profile.getUserType().equalsIgnoreCase(Constants.STAFF_ROLE)){
throw new AuthenticationException("Unauthorized web platform user");
}
return;
case MOBILE:
if (!profile.getUserType().equalsIgnoreCase(Constants.AGENT_ROLE)){
throw new AuthenticationException("Unauthorized mobile platform user");
}
return;
case AGGREGATOR:
if(!profile.getRoles().add("AGGREGATOR_ROLE")){
throw new AuthenticationException("Unauthorized aggregator");
}
default:
throw new AuthenticationException("Unauthorized! Unknown platform");
}
}
private String generateToken(ClPrincipal principal) throws JoseException {
final JwtClaims claims = new JwtClaims();
claims.setSubject(principal.getProfileId());
claims.setStringClaim(Constants.USERNAME, principal.getUsername());
claims.setStringClaim(Constants.FIRST_NAME, principal.getFirstname());
claims.setStringClaim(Constants.LAST_NAME, principal.getLastname());
claims.setStringClaim(Constants.ROLE_GROUP, principal.getRoleGroup());
claims.setStringListClaim(Constants.ROLES, principal.getRoles());
claims.setExpirationTimeMinutesInTheFuture(oAuthConfig.getTokenTTL() / 60);
claims.setJwtId(UUID.randomUUID().toString())
What do I do to get the desired result I stated earlier. I keep getting the default message for the switch case ("Unauthorized! Unknown platform")

Java webservice client with ADFS SAML authentication

We are trying to connect to webservice (from Java) that has ADFS SAML authentication.
All the examples I have seen, use Basic Authentication over HTTPS. (I am just using HttpsURLConnection to make a request for now, not using anything like Axis or JAX-WS)
I am not sure how to approach ADFS SAML authentication. Here's what I understand so far (don't know much about SAML):
I make one request, pass username/password and get the
authentication token back
Save the authentication token
Pass the token as some SOAP attribute in my calls where I invoke an
actual operation on the webservice
No idea under which attribute would I put this authentication token though
Is my above approach correct? If so, is there some library that I can use that does all this?
If not how can I go about doing this manually?
Please let me know if there are other or better ways of going about this.
If you are trying to build native app then can use below code. i has tried to use power bi rest apis. once you gets token you can use that in api calls.
public class PublicClient {
private final static String AUTHORITY = "https://login.microsoftonline.com/common";
private final static String CLIENT_ID = "XXXX-xxxx-xxx-xxx-xxxX";
private final static String RESOURCE = "https://analysis.windows.net/powerbi/api";
public static void main(String args[]) throws Exception {
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
System.out.print("Enter username: ");
String username = br.readLine();
System.out.print("Enter password: ");
String password = br.readLine();
AuthenticationResult result = getAccessTokenFromUserCredentials(
username, password);
System.out.println("Access Token - " + result.getAccessToken());
System.out.println("Refresh Token - " + result.getRefreshToken());
System.out.println("ID Token Expires on - " + result.getExpiresOn());
}
}
private static AuthenticationResult getAccessTokenFromUserCredentials(
String username, String password) throws Exception {
AuthenticationContext context = null;
AuthenticationResult result = null;
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(1);
context = new AuthenticationContext(AUTHORITY, false, service);
Future<AuthenticationResult> future = context.acquireToken(
RESOURCE, CLIENT_ID, username, password, null);
result = future.get();
} finally {
service.shutdown();
}
if (result == null) {
throw new ServiceUnavailableException(
"authentication result was null");
}
return result;
}
}

How to show browser login form for basic authentication using RESTEasy

I´m currently messing around with JAX-RS specifically Resteasy, because it "just works" with Wildfly and I don´t have to configure anything. That´s really the only reason I use that.
I did already implement Basic Authentication, looking forward to replacing it with OAuth2 later, just did this now for simplicity reasons.
The ContainerRequestFilter looks like this
#Provider
public class SecurityFilter implements ContainerRequestFilter {
private static final String AUTHORIZATION_HEADER_KEY = "Authorization";
private static final String AUTHORIZATION_HEADER_PREFIX = "Basic ";
#Override
public void filter(ContainerRequestContext containerRequestContext) throws IOException {
if(isAuthenticated(containerRequestContext) == false)
containerRequestContext.abortWith(createUnauthorizedResponse("Access denied."));
}
private boolean isAuthenticated(ContainerRequestContext containerRequestContext) {
List<String> authHeader = containerRequestContext.getHeaders().get(AUTHORIZATION_HEADER_KEY);
ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) containerRequestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker");
Method method = methodInvoker.getMethod();
RolesAllowed rolesAnnotation = method.getAnnotation(RolesAllowed.class);
if (authHeader != null && authHeader.size() > 0) {
String authToken = authHeader.get(0).replaceFirst(AUTHORIZATION_HEADER_PREFIX, "");
byte[] decoded = null;
try {
decoded = Base64.getDecoder().decode(authToken);
} catch (IllegalArgumentException ex) {
return false;
}
String decodedString = new String(decoded);
StringTokenizer tokenizer = new StringTokenizer(decodedString, ":");
String username = null, password = null;
if(tokenizer.countTokens() < 2)
return false;
username = tokenizer.nextToken();
password = tokenizer.nextToken();
if (DbController.isValid(username, password, rolesAnnotation.value()))
return true;
}
return false;
}
private Response createUnauthorizedResponse(String msg) {
return Response.status(Response.Status.UNAUTHORIZED)
.entity("{ \"Unauthorized\" : \"" + msg + "\" }")
.type(MediaType.APPLICATION_JSON)
.build();
}
}
It works fine with postman. And I do realize that the main usage of such apis is in well other programs.
But it would be nice, if opened in a browser it would ask you to enter your credentials, instead of just telling you that you are not authorized, with no way to really enter your credentials. Unless you do some trickery to manually put it in the header, but then you might as well just use postman.
If I put a security constraint with auth-constraint role admin it does give a login dialog, but then the authorization does not work and it just keeps asking for authorization.
Is there anything else that I can do instead of containerRequestContext.abortWith? Or do I need to use a completely different approach and it just won´t work with ContainerRequestFilter?
You need to add the WWW-Authenticate header to the response that you abort with. This header tells the browser that it should present the default browser login form.
private static final String CHALLENGE_FORMAT = "%s realm=\"%s\"";
private Response createUnauthorizedResponse() {
return Response.status(Response.Status.UNAUTHORIZED)
.header(HttpHeaders.WWW_AUTHENTICATE, String.format(CHALLENGE_FORMAT, "Basic", "Access"))
.type(MediaType.TEXT_PLAIN_TYPE)
.entity("Credentials are required to access this resource.")
.build();
And here's what the login should look like on Chrome

Bonita Web API - 401 Unauthorized Error

I am trying to use Bonita Web API. I My code is below. As you can see I call the loginservice before calling any other API service. It logs in OK 200. But when I make the subsequent call to get the list of processes I get a 401 error. You get a JSESSIONID from the first call and you are suppose to pass it to the subsequent calls to authenticate you.
var baseAddress = new Uri(<base address>);
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
HttpResponseMessage result = client.PostAsync("/bonita/loginservice", new StringContent("login=<username>,password=<password>,redirect=false")).Result;
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage result2 = client.GetAsync("/bonita/API/bpm/process").Result;
result2.EnsureSuccessStatusCode();
}
This works for .Net 2.0 C# but has some interesting things to check.
WebClient wc = new WebClient();
wc.Proxy = WebRequest.GetSystemWebProxy();
//wc.Headers[HttpRequestHeader.AcceptEncoding] = "gzip, deflate";
string strLogin = wc.DownloadString("http://localhost:8080/bonita/loginservice?username=walter.bates&password=bpm&redirect=false");
wc.Headers[HttpRequestHeader.Cookie] = wc.ResponseHeaders[HttpResponseHeader.SetCookie].ToString();
string strCookie = wc.ResponseHeaders[HttpResponseHeader.SetCookie].ToString();
string strProcesses = wc.DownloadString("http://localhost:8080/bonita/API/bpm/process?p=0");
First of all you should know how to determine that the executed operation is successful ( login, getProcesses and whatever) When you try to login you will always get the header (for example "JSESSIONID=50E509D37AC28E2D725CBD45A8112FA7; Path=/bonita; HttpOnly") and OK 200 even if your login attempt in Bonita is unsuccesful.
For the successful login on the previous example
1) You must Pass mandatory form data: username, password and redirect You must also be sure to pass redirect in lower case ."False" will not work, "false" will work. So for .Net suppose you have a property-> Boolean redirect. You must make it lowercase with redirect.ToString().ToLower() cause either way the value will be "False" and you don't want that.
Let's say you try to login only with username and password without passing redirect. the result is that you will get both OK 200 and the header but you will also get a response which is wrong (the response must be empty), so on the next request (i.e getProcesses) you'll get (401) Unauthorized. Guess the results you will have if you pass redirect=False instead of redirect=false. Exactly the same.
2)You must get: strLogin="" // the body of the response must be empty strCookie="JSESSIONID=4F67F134840A2C72DBB968D53772FB22; Path=/bonita; HttpOnly"
For the successful getProcesses on the previous example you pass the header you got from login
wc.Headers[HttpRequestHeader.Cookie] = wc.ResponseHeaders[HttpResponseHeader.SetCookie].ToString();
and then you call the process and get a string in json format for example
"[{\"id\":\"6996906669894804403\",\"icon\":\"\",\"displayDescription\":\"\",\"deploymentDate\":\"2014-11-19 17:57:40.893\",\"description\":\"\",\"activationState\":\"ENABLED\",\"name\":\"Travel request\",\"deployedBy\":\"22\",\"displayName\":\"Travel request\",\"actorinitiatorid\":\"4\",\"last_update_date\":\"2014-11-19 17:57:41.753\",\"configurationState\":\"RESOLVED\",\"version\":\"1.0\"}]"
(or [] which means an empty json)
If the cookie is not passed correctly you will get again 401 error.
Solution for .Net 4.5.1
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace BonitaRestApi
{
class BonitaApi
{
private CookieCollection collection;
string strCookietoPass;
string sessionID;
static void Main(string[] args)
{
BonitaApi obj = new BonitaApi();
Task login = new Task(obj.Login);
login.Start();
login.Wait();
Console.ReadLine();
Task GetProcesses = new Task(obj.GetProcesses);
GetProcesses.Start();
GetProcesses.Wait();
Console.ReadLine();
Task logout = new Task(obj.Logout);
logout.Start();
logout.Wait();
Console.ReadLine();
}
public async void Login()
{
const string url = "http://localhost:8080/bonita/";
var cookies = new CookieContainer();
var handler = new HttpClientHandler();
handler.CookieContainer = cookies;
using (var client = new HttpClient(handler))
{
var uri = new Uri(url);
client.BaseAddress = uri;
//client.DefaultRequestHeaders.Accept.Clear();
//client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("username", "helen.kelly"),
new KeyValuePair<string, string>("password", "bpm"),
new KeyValuePair<string, string>("redirect", "false"),
new KeyValuePair<string, string>("redirectUrl", ""),
});
HttpResponseMessage response = await client.PostAsync("loginservice", content);
if (response.IsSuccessStatusCode)
{
var responseBodyAsText = await response.Content.ReadAsStringAsync();
if (!String.IsNullOrEmpty(responseBodyAsText))
{
Console.WriteLine("Unsuccessful Login.Bonita bundle may not have been started, or the URL is invalid.");
return;
}
collection= cookies.GetCookies(uri);
strCookietoPass = response.Headers.GetValues("Set-Cookie").FirstOrDefault();
sessionID = collection["JSESSIONID"].ToString();
Console.WriteLine(string.Format("Successful Login Retrieved session ID {0}", sessionID));
// Do useful work
}
else
{
Console.WriteLine("Login Error" + (int)response.StatusCode + "," + response.ReasonPhrase);
}
}
}
public async void Logout()
{
const string url = "http://localhost:8080/bonita/";
var cookies = new CookieContainer();
var handler = new HttpClientHandler();
handler.CookieContainer = cookies;
using (var client = new HttpClient(handler))
{
var uri = new Uri(url);
client.BaseAddress = uri;
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("redirect", "false")
});
HttpResponseMessage response = await client.PostAsync("logoutservice", content);
if (response.IsSuccessStatusCode)
{
var responseBodyText = await response.Content.ReadAsStringAsync();
if (!String.IsNullOrEmpty(responseBodyText))
{
Console.WriteLine("Unsuccessful Logout.Bonita bundle may not have been started, or the URL is invalid.");
return;
}
Console.WriteLine("Successfully Logged out.");
}
else
{
Console.WriteLine("Logout Error" + (int)response.StatusCode + "," + response.ReasonPhrase);
}
}
}
public async void GetProcesses()
{
var handler = new HttpClientHandler();
Cookie ok = new Cookie("Set-Cookie:",strCookietoPass);
handler.CookieContainer.Add(collection);
using (var client = new HttpClient(handler))
{
var builder = new UriBuilder("http://localhost/bonita/API/bpm/process");
builder.Port = 8080;
var query = HttpUtility.ParseQueryString(builder.Query);
query["p"] = "0";
query["c"] = "10";
builder.Query = query.ToString();
Uri uri= new Uri(builder.ToString());
client.BaseAddress = uri;
HttpResponseMessage response = await client.GetAsync(uri.ToString());
if (response.IsSuccessStatusCode)
{
var responseBodyText = await response.Content.ReadAsStringAsync();
if (String.IsNullOrEmpty(responseBodyText))
{
Console.WriteLine("Unsuccessful GetProcesses.Bonita bundle may not have been started, or the URL is invalid.");
return;
}
Console.WriteLine("Successfully GetProcesses:" + responseBodyText);
}
else
{
Console.WriteLine("GetProcesses Error" + (int)response.StatusCode + "," + response.ReasonPhrase);
}
}
}
}
}
I had the same problem (401 errors) for every single non-GET request.
I finally got through this by looking to the CSRF documentation:
http://documentation.bonitasoft.com/7.4?page=csrf-security
(See the "Is there an impact on REST API calls?" section)
After succesfull login, you have to put a special header in your request:
key: X-Bonita-API-Token
value: the one you got after your login (check the relevant cookie)

GWT Facebook Integration

I am trying to write a server side Facebook Notification service in my GWT app. The idea is that I will run this as a timertask or cron job sort of.
With the code below, I get a login URL, I want to be able to Login programmatically as this is intended to be automated (Headless sort of way). I was gonna try do a submit with HTMLunit but I thought the FB API should cater for this.
Please advice.
public class NotificationServiceImpl extends RemoteServiceServlet implements NotificationService {
/**serialVersionUID*/
private static final long serialVersionUID = 6893572879522128833L;
private static final String FACEBOOK_USER_CLIENT = "facebook.user.client";
long facebookUserID;
public String sendMessage(Notification notification) throws IOException {
String api_key = notification.getApi_key();
String secret = notification.getSecret_key();
try {
// MDC.put(ipAddress, req.getRemoteAddr());
HttpServletRequest request = getThreadLocalRequest();
HttpServletResponse response = getThreadLocalResponse();
HttpSession session = getThreadLocalRequest().getSession(true);
// session.setAttribute("api_key", api_key);
IFacebookRestClient<Document> userClient = getUserClient(session);
if(userClient == null) {
System.out.println("User session doesn't have a Facebook API client setup yet. Creating one and storing it in the user's session.");
userClient = new FacebookXmlRestClient(api_key, secret);
session.setAttribute(FACEBOOK_USER_CLIENT, userClient);
}
System.out.println("Creating a FacebookWebappHelper, which copies fb_ request param data into the userClient");
FacebookWebappHelper<Document> facebook = new FacebookWebappHelper<Document>(request, response, api_key, secret, userClient);
String nextPage = request.getRequestURI();
nextPage = nextPage.substring(nextPage.indexOf("/", 1) + 1); //cut out the first /, the context path and the 2nd /
System.out.println(nextPage);
boolean redirectOccurred = facebook.requireLogin(nextPage);
if(redirectOccurred) {
return null;
}
redirectOccurred = facebook.requireFrame(nextPage);
if(redirectOccurred) {
return null;
}
try {
facebookUserID = userClient.users_getLoggedInUser();
if (userClient.users_hasAppPermission(Permission.STATUS_UPDATE)) {
userClient.users_setStatus("Im testing Facebook With Java! This status is written using my Java code! Can you see it? Cool :D", false);
}
} catch(FacebookException ex) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error while fetching user's facebook ID");
System.out.println("Error while getting cached (supplied by request params) value " +
"of the user's facebook ID or while fetching it from the Facebook service " +
"if the cached value was not present for some reason. Cached value = {}" + userClient.getCacheUserId());
return null;
}
// MDC.put(facebookUserId, String.valueOf(facebookUserID));
// chain.doFilter(request, response);
} finally {
// MDC.remove(ipAddress);
// MDC.remove(facebookUserId);
}
return String.valueOf(facebookUserID);
}
public static FacebookXmlRestClient getUserClient(HttpSession session) {
return (FacebookXmlRestClient)session.getAttribute(FACEBOOK_USER_CLIENT);
}
}
Error message:
[ERROR] com.google.gwt.user.client.rpc.InvocationException: <script type="text/javascript">
[ERROR] top.location.href = "http://www.facebook.com/login.php?v=1.0&api_key=MY_KEY&next=notification";
[ERROR] </script>

Categories