I am working on Restlet tutorial example concerning coarse-grained authorization:
public class MyApiWithRoleAuthorization extends Application {
//Define role names
public static final String ROLE_USER = "user";
public static final String ROLE_OWNER = "owner";
#Override
public Restlet createInboundRoot() {
//Create the authenticator, the authorizer and the router that will be protected
ChallengeAuthenticator authenticator = createAuthenticator();
RoleAuthorizer authorizer = createRoleAuthorizer();
Router router = createRouter();
Router baseRouter = new Router(getContext());
//Protect the resource by enforcing authentication then authorization
authorizer.setNext(Resource0.class);
authenticator.setNext(baseRouter);
//Protect only the private resources with authorizer
//You could use several different authorizers to authorize different roles
baseRouter.attach("/resourceTypePrivate", authorizer);
baseRouter.attach("/resourceTypePublic", router);
return authenticator;
}
private ChallengeAuthenticator createAuthenticator() {
ChallengeAuthenticator guard = new ChallengeAuthenticator(
getContext(), ChallengeScheme.HTTP_BASIC, "realm");
//Create in-memory users with roles
MemoryRealm realm = new MemoryRealm();
User user = new User("user", "user");
realm.getUsers().add(user);
realm.map(user, Role.get(this, ROLE_USER));
User owner = new User("owner", "owner");
realm.getUsers().add(owner);
realm.map(owner, Role.get(this, ROLE_OWNER));
//Attach verifier to check authentication and enroler to determine roles
guard.setVerifier(realm.getVerifier());
guard.setEnroler(realm.getEnroler());
return guard;
}
private RoleAuthorizer createRoleAuthorizer() {
//Authorize owners and forbid users on roleAuth's children
RoleAuthorizer roleAuth = new RoleAuthorizer();
roleAuth.getAuthorizedRoles().add(Role.get(this, ROLE_OWNER));
roleAuth.getForbiddenRoles().add(Role.get(this, ROLE_USER));
return roleAuth;
}
private Router createRouter() {
//Attach Server Resources to given URL
Router router = new Router(getContext());
router.attach("/resource1/", Resource1.class);
router.attach("/resource2/", Resource2.class);
return router;
}
public static void main(String[] args) throws Exception {
//Attach application to http://localhost:9000/v1
Component c = new Component();
c.getServers().add(Protocol.HTTP, 9000);
c.getDefaultHost().attach("/v1", new MyApiWithRoleAuthorization());
c.start();
}
}
I create a class for checking user credentials:
public class Resource1 extends ServerResource{
#Get
public String represent() throws Exception {
User user = getRequest().getClientInfo().getUser();
String identifier = user.getIdentifier();
char[] pass = user.getSecret();
return this.getClass().getSimpleName() + " found ! User: " + identifier +
"; password = " + charArrayToString(pass) ;
}
private String charArrayToString(char[] chars ) {
String result = "";
for (char c : chars){
result += c;
}
return result;
}
}
When I go to resource http://localhost:9000/v1/resourceTypePublic/resource1/ the application asks for credentials and I input "user", "user" (or "owner", "owner"). But I get internal server error. The reason is that variable pass in return statement
return this.getClass().getSimpleName() + " found ! User: " + identifier +
"; password = " + charArrayToString(pass) ;
has null value. The statement without this variable works ok:
return this.getClass().getSimpleName() + " found ! User: " + identifier;
and returns user login. But what about the secret? Why it returns null value despite the user secret had been inputted?
User object created with statement
User user = getRequest().getClientInfo().getUser();
does not contain information about password despite it has a field secret. There is another way to get user credentials:
char[] pass = getChallengeResponse().getSecret();
Related
I am trying create one application from where I can get the all the information related to user/Tracks/Album.
I have used below code for authentication using clientid and client secret id.
private static String clintId = "generated id";
private static String clientSecretId = "generated secret id";
private static final URI redirectUri = SpotifyHttpManager.makeUri("http://localhost:8080/api/get-user-code/");
public static final SpotifyApi spotifyApi = new SpotifyApi.Builder()
.setClientId(clintId)
.setClientSecret(clientSecretId)
.setRedirectUri(redirectUri)
.build();
#GetMapping("login")
#ResponseBody
public String spotifyLogin(){
AuthorizationCodeUriRequest authorizationCodeUriRequest = spotifyApi.authorizationCodeUri()
.scope("user-read-private user-read-email user-top-read user-library-read user-library-modify")
.show_dialog(true)
.build();
final URI uri = authorizationCodeUriRequest.execute();
return uri.toString();
}
#GetMapping(value="get-user-code")
public void getSpotifyUserCode(#RequestParam("code") String userCode, HttpServletResponse response) throws IOException {
AuthorizationCodeRequest authorizationCodeRequest = spotifyApi.authorizationCode(userCode)
.build();
try {
final AuthorizationCodeCredentials authorizationCodeCredentials = authorizationCodeRequest.execute();
// Set access and refresh token for further "spotifyApi" object usage
System.out.println("Access token::"+authorizationCodeCredentials.getAccessToken());
spotifyApi.setAccessToken(authorizationCodeCredentials.getAccessToken());
spotifyApi.setRefreshToken(authorizationCodeCredentials.getRefreshToken());
System.out.println("Expires in: " + authorizationCodeCredentials.getExpiresIn());
} catch (IOException | SpotifyWebApiException | org.apache.hc.core5.http.ParseException e){
System.out.println("Error: " + e.getMessage());
}
response.sendRedirect("http://localhost:3000/home");
}
Now take one example: Suppose I have created above client id and secret id from User A (From development dashboard) so for User A everything is working fine like I am able to get user profile, Track etc.
But suppose if I try to get same details for User B like user profile/tracks etc with User A generated client id and secret id then not able to get those information for User B its showing "forbidden".
So my question is that how to get those information for user B (with user A client id and secret details)?
I am testing android managment API using localhost as call back url. I followed each and every step following this url Android Management API Sample.
Now i m stuck on place.. according to this guide, i download the json file from service account. Now i copy that json file and save in app folder of my project.
This is my enterprise.json file
Screenshot of json file in android studio
and i just give folder location as enterprise.json in location string
This is my code
private static final String PROJECT_ID = "enterprise-271814";
private static final String SERVICE_ACCOUNT_CREDENTIAL_FILE =
"enterprise.json";
private static final String POLICY_ID = "samplePolicy";
/** The package name of the COSU app. */
private static final String COSU_APP_PACKAGE_NAME =
"com.ariaware.devicepoliceycontroller";
/** The OAuth scope for the Android Management API. */
private static final String OAUTH_SCOPE =
"https://www.googleapis.com/auth/androidmanagement";
private static final String APP_NAME = "Device Policey Controller";
private final AndroidManagement androidManagementClient;
public Sample(AndroidManagement androidManagementClient) {
this.androidManagementClient = androidManagementClient;
}
public void run() throws IOException {
// Create an enterprise. If you've already created an enterprise, the
// createEnterprise call can be commented out and replaced with your
// enterprise name.
String enterpriseName = createEnterprise();
System.out.println("Enterprise created with name: " + enterpriseName);
// Set the policy to be used by the device.
setPolicy(enterpriseName, POLICY_ID, getCosuPolicy());
// Create an enrollment token to enroll the device.
String token = createEnrollmentToken(enterpriseName, POLICY_ID);
System.out.println("Enrollment token (to be typed on device): " + token);
// List some of the devices for the enterprise. There will be no devices for
// a newly created enterprise, but you can run the app again with an
// existing enterprise after enrolling a device.
List<Device> devices = listDevices(enterpriseName);
for (Device device : devices) {
System.out.println("Found device with name: " + device.getName());
}
// If there are any devices, reboot one.
if (devices.isEmpty()) {
System.out.println("No devices found.");
} else {
rebootDevice(devices.get(0));
}
}
public static AndroidManagement getAndroidManagementClient()
throws IOException, GeneralSecurityException {
try (FileInputStream input =
new FileInputStream(SERVICE_ACCOUNT_CREDENTIAL_FILE)) {
GoogleCredential credential =
GoogleCredential.fromStream(input)
.createScoped(Collections.singleton(OAUTH_SCOPE));
return new AndroidManagement.Builder(
GoogleNetHttpTransport.newTrustedTransport(),
JacksonFactory.getDefaultInstance(),
credential)
.setApplicationName(APP_NAME)
.build();
}
}
private String createEnterprise() throws IOException {
// Initiate signup process.
System.out.println("Creating signup URL...");
SignupUrl signupUrl =
androidManagementClient
.signupUrls()
.create()
.setProjectId(PROJECT_ID)
.setCallbackUrl("https://localhost:9999")
.execute();
System.out.print(
"To sign up for a new enterprise, open this URL in your browser: ");
System.out.println(signupUrl.getUrl());
System.out.println(
"After signup, you will see an error page in the browser.");
System.out.print(
"Paste the enterpriseToken value from the error page URL here: ");
String enterpriseToken =
new BufferedReader(new InputStreamReader(System.in)).readLine();
// Create the enterprise.
System.out.println("Creating enterprise...");
return androidManagementClient
.enterprises()
.create(new Enterprise())
.setProjectId(PROJECT_ID)
.setSignupUrlName(signupUrl.getName())
.setEnterpriseToken(enterpriseToken)
.execute()
.getName();
}
private Policy getCosuPolicy() {
List<String> categories = new ArrayList<>();
categories.add("android.intent.category.HOME");
categories.add("android.intent.category.DEFAULT");
return new Policy()
.setApplications(
Collections.singletonList(
new ApplicationPolicy()
.setPackageName(COSU_APP_PACKAGE_NAME)
.setInstallType("FORCE_INSTALLED")
.setDefaultPermissionPolicy("GRANT")
.setLockTaskAllowed(true)))
.setPersistentPreferredActivities(
Collections.singletonList(
new PersistentPreferredActivity()
.setReceiverActivity(COSU_APP_PACKAGE_NAME)
.setActions(
Collections.singletonList("android.intent.action.MAIN"))
.setCategories(categories)))
.setKeyguardDisabled(true)
.setStatusBarDisabled(true);
}
private void setPolicy(String enterpriseName, String policyId, Policy policy)
throws IOException {
System.out.println("Setting policy...");
String name = enterpriseName + "/policies/" + policyId;
androidManagementClient
.enterprises()
.policies()
.patch(name, policy)
.execute();
}
private String createEnrollmentToken(String enterpriseName, String policyId)
throws IOException {
System.out.println("Creating enrollment token...");
EnrollmentToken token =
new EnrollmentToken().setPolicyName(policyId).setDuration("86400s");
return androidManagementClient
.enterprises()
.enrollmentTokens()
.create(enterpriseName, token)
.execute()
.getValue();
}
private List<Device> listDevices(String enterpriseName) throws IOException {
System.out.println("Listing devices...");
ListDevicesResponse response =
androidManagementClient
.enterprises()
.devices()
.list(enterpriseName)
.execute();
return response.getDevices() ==null
? new ArrayList<Device>() : response.getDevices();
}
private void rebootDevice(Device device) throws IOException {
System.out.println(
"Sending reboot command to " + device.getName() + "...");
Command command = new Command().setType("REBOOT");
androidManagementClient
.enterprises()
.devices()
.issueCommand(device.getName(), command)
.execute();
}
Moreover i m using android management api for the first time and i dont know its proper implementation. Anyone who has experience on this kinllt guide me a little bit. I found a lot about this but i didn't found any userful tutorial
For Android, you have to store the service account file either in the assets folder or raw folder.
This thread provides code on a number of ways to load the json data into an InputStream depending on the location you selected.
In my current java/spring project, I am using the paypal-java-sdk to try implement a payment system to my application. A long time ago, I managed to make this work with a old project I've lost, with a code similar to what I have now, but now, when I run the application and try make a payment using the paypal sdk, I am redirect to the payment method selection page, and, either if I confirm or cancel the payment, I go to my account page instead of return to the application.
I have this code:
in my controller, this method receives the call from the view:
#RequestMapping(value = "/checkout", method=RequestMethod.GET)
public String checkout(#RequestParam("usuario_id") Integer usuario_id, #RequestParam(value="payerId", required=false) String payerId, #RequestParam(value="guid", required=false) String guid) throws com.paypal.base.rest.PayPalRESTException {
return "redirect:"+this.serv.checkout(usuario_id, payerId, guid);
}
in my service class, this 2 methods handles the payment using paypal:
public String checkout(Integer usuario_id, String payerId, String guid) throws com.paypal.base.rest.PayPalRESTException {
Usuario usuario = this.dao.findBy("id", usuario_id);
String clientId = paypalDao.get().getClientId();
String clientSecret = paypalDao.get().getClientSecret();
APIContext apiContext = new APIContext(clientId, clientSecret, "sandbox");
String redirectURL = "";
if(payerId != null) {
if(guid != null) {
Payment payment = new Payment();
payment.setId(map.get(guid));
PaymentExecution paymentExecution = new PaymentExecution();
paymentExecution.setPayerId(payerId);
payment.execute(apiContext, paymentExecution);
//saves the order data in the database and redirect to the order page
}
} else {
Payment createdPayment = createPayment(usuario, apiContext);
Iterator<Links> links = createdPayment.getLinks().iterator();
while (links.hasNext()) {
Links link = links.next();
if (link.getRel().equalsIgnoreCase("approval_url"))
redirectURL = link.getHref();
}
map.put(guid, createdPayment.getId());
}
return redirectURL;
}
public Payment createPayment(Usuario usuario, APIContext apiContext) throws com.paypal.base.rest.PayPalRESTException {
Amount amount = new Amount();
amount.setCurrency("BRL");
amount.setTotal(this.cart_total(usuario.getId()).toString());
String desc = "Lista de produtos comprados\n";
for(Produto produto : usuario.getCesta().getProdutos())
desc = desc + "* " + produto.getNome() + "\n";
Transaction transaction = new Transaction();
transaction.setAmount(amount);
transaction.setDescription(desc);
java.util.List<Transaction> transactions = new java.util.ArrayList<Transaction>();
transactions.add(transaction);
Payer payer = new Payer();
payer.setPaymentMethod("paypal");
Payment payment = new Payment();
payment.setIntent("sale");
payment.setPayer(payer);
payment.setTransactions(transactions);
RedirectUrls redirectUrls = new RedirectUrls();
redirectUrls.setCancelUrl(request.getContextPath() + "/cancel");
redirectUrls.setReturnUrl(request.getContextPath() + "/checkout?usuario_id="+usuario.getId()+"?guid="+UUID.randomUUID().toString());
payment.setRedirectUrls(redirectUrls);
return payment.create(apiContext);
}
anyone can give me a hint of what I am missing here?
I have recently had to some trouble trying to get OpenID to work in Java (servlet). I'm trying to make a user able to login to my website using their Steam account. I've tried mutliple libraries but some of them are outdated and for others is almost no documentation available so the library I'm trying right now is JOpenID. It works as expected until I need to verify the information sent back by Steam (http://steamcommunity.com/openid). This is my Servlet:
#WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private OpenIdManager manager;
static final long ONE_HOUR = 3600000L;
static final long TWO_HOUR = ONE_HOUR * 2L;
static final String ATTR_MAC = "openid_mac";
static final String ATTR_ALIAS = "openid_alias";
public LoginServlet() {
super();
}
#Override
public void init() throws ServletException {
super.init();
manager = new OpenIdManager();
manager.setRealm("http://localhost:8080/TestServletProject/LoginServlet");
manager.setReturnTo("http://localhost:8080/TestServletProject/LoginServlet?login=verify");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
String login = request.getParameter("login");
if(login != null){
if(login.equals("steam")){
out.print("<h2>Redirecting</h2>");
Endpoint endpoint = manager.lookupEndpoint("http://steamcommunity.com/openid");
Association association = manager.lookupAssociation(endpoint);
request.getSession().setAttribute(ATTR_MAC, association.getRawMacKey());
request.getSession().setAttribute(ATTR_ALIAS, endpoint.getAlias());
String url = manager.getAuthenticationUrl(endpoint, association);
response.sendRedirect(url);
}else if(login.equals("verify")){
checkNonce(request.getParameter("openid.response_nonce"));
byte[] mac_key = (byte[]) request.getSession().getAttribute(ATTR_MAC);
String alias = (String) request.getSession().getAttribute(ATTR_ALIAS);
Authentication authentication = manager.getAuthentication(request, mac_key, alias);
response.setContentType("text/html; charset=UTF-8");
showAuthentication(response.getWriter(), authentication);
return;
}else if(login.equals("logout")){
out.print("<h2>Loggin out</h2>");
}
return;
}
String id = (String) request.getSession().getAttribute("steamid");
if (id != null) {
out.print("<h2>Welcome ");
out.print(id);
out.print("</h2>");
out.print("Logout");
} else {
out.print("Login");
}
}
void showAuthentication(PrintWriter pw, Authentication auth) {
pw.print("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /><title>Test JOpenID</title></head><body><h1>You have successfully signed on!</h1>");
pw.print("<p>Identity: " + auth.getIdentity() + "</p>");
pw.print("<p>Email: " + auth.getEmail() + "</p>");
pw.print("<p>Full name: " + auth.getFullname() + "</p>");
pw.print("<p>First name: " + auth.getFirstname() + "</p>");
pw.print("<p>Last name: " + auth.getLastname() + "</p>");
pw.print("<p>Gender: " + auth.getGender() + "</p>");
pw.print("<p>Language: " + auth.getLanguage() + "</p>");
pw.print("</body></html>");
pw.flush();
}
void checkNonce(String nonce) {
// check response_nonce to prevent replay-attack:
if (nonce==null || nonce.length()<20)
throw new OpenIdException("Verify failed.");
// make sure the time of server is correct:
long nonceTime = getNonceTime(nonce);
long diff = Math.abs(System.currentTimeMillis() - nonceTime);
if (diff > ONE_HOUR)
throw new OpenIdException("Bad nonce time.");
if (isNonceExist(nonce))
throw new OpenIdException("Verify nonce failed.");
storeNonce(nonce, nonceTime + TWO_HOUR);
}
private Set<String> nonceDb = new HashSet<String>();
// check if nonce is exist in database:
boolean isNonceExist(String nonce) {
return nonceDb.contains(nonce);
}
// store nonce in database:
void storeNonce(String nonce, long expires) {
nonceDb.add(nonce);
}
long getNonceTime(String nonce) {
try {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.parse(nonce.substring(0, 19) + "+0000")
.getTime();
}
catch(ParseException e) {
throw new OpenIdException("Bad nonce time.");
}
}
}
I'm getting a org.expressme.openid.OpenIdException: Invalidate handle on line 65: Authentication authentication = manager.getAuthentication(request, mac_key, alias);
While doing some research I found out that this had to do with the Assosiaction sent to steam being expired. This is the JOpenID class that causes the OpenIdException: https://github.com/michaelliao/jopenid/blob/master/src/main/java/org/expressme/openid/OpenIdManager.java
Does anybody know how I can get this to work, or alternatively, know a better library to use. I'm quite new to this and I'm not sure if I'm using the right library or if there's better ways to do this.
So for anyone still wondering: I looked into the JOpenID code and it seems like the code in the getAuthentication() method that goes before the code that throws the exception is enough to retrieve the Steam ID (which is what I tried to get from Steam). So instead of Authentication authentication = manager.getAuthentication(request, mac_key, alias); I now just put String identity = request.getParameter("openid.identity");. This returns http://steamcommunity.com/openid/id/76561198206376959, last part being the Steam ID.
I have uploaded a test html page and servlet following this article exactly. This works and will send me an email. However, when I copy this code almost exactly into my SendEmail method in the code shown below it does not send an email. I know when I run this locally that it gets to the SendEmail method just fine (but you cannot send emails using the development server in GAE). When I deploy it there are no errors on the page or in the logs so it plain old seems like it is just not sending the email. Anyone see a reason why?
public class EmailService {
private static SimpleDateFormat dateFormatter = new SimpleDateFormat ("MM/dd/yyyy");
public static void SendDeadlineEmails() {
PersistenceManager pm = getPersistenceManager();
try {
List<DeadlineEmailObject> studentsWithDeadlineToday = populateEmailList(pm);
sendEmails(studentsWithDeadlineToday);
} finally {
pm.close();
}
}
private static List<DeadlineEmailObject> populateEmailList(PersistenceManager pm) {
List<Student> students = getStudents(pm);
List<DeadlineEmailObject> studentsWithDeadlineToday = new ArrayList<DeadlineEmailObject>();
String today = dateFormatter.format(System.currentTimeMillis());
for(Student student : students) {
Set<Charge> charges = student.getCharges();
if(charges != null) {
for(Charge charge : charges) {
String deadline = dateFormatter.format(charge.getDeadline());
if(deadline.equals(today)) {
studentsWithDeadlineToday.add(new DeadlineEmailObject(student, charge));
}
}
}
}
return studentsWithDeadlineToday;
}
#SuppressWarnings("unchecked")
private static List<Student> getStudents(PersistenceManager pm) {
return (List<Student>) pm.newQuery(Student.class).execute();
}
private static void sendEmails(List<DeadlineEmailObject> studentsWithDeadlineToday) {
for(DeadlineEmailObject emailObj : studentsWithDeadlineToday) {
sendEmail(emailObj);
System.out.println("Student: " + emailObj.getStudent().getFullName() + "\nAmount: " + emailObj.getCharge().getAmount() +
"\nDeadline: " + dateFormatter.format(emailObj.getCharge().getDeadline()));
}
}
private static void sendEmail(DeadlineEmailObject emailObj) {
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
try {
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("njbuwm#gmail.com", "Admin"));
msg.addRecipient(Message.RecipientType.TO, new InternetAddress(emailObj.getStudent().getEmail(), emailObj.getStudent().getFullName()));
msg.setSubject("Deadline Reached");
msg.setText(buildMessage(emailObj));
Transport.send(msg);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static String buildMessage(DeadlineEmailObject emailObj) {
String email = "";
email += "Dear " + emailObj.getStudent().getFullName() + " ,\n";
email += "You owe us money. This much: $" + emailObj.getCharge().getAmount() + ".\n";
email += "For this reason: " + emailObj.getCharge().getReason() + ".\n";
email += "The deadline is today and I advise you to pay it or you will be deported to Idontpaymybills Island forever.\n";
email += "Thank you,\n Automated Emailer";
return email;
}
private static PersistenceManager getPersistenceManager() {
return JDOHelper.getPersistenceManagerFactory("transactions-optional").getPersistenceManager();
}
}
Change your call to setFrom() to use an email address permitted in the Developers Guide:
To set the sender address, the app calls the setFrom() method on the
MimeMessage object. The sender address must be one of the following
types:
The address of a registered administrator for the application
The address of the user for the current request signed in with a Google Account. You can determine the current user's email address with the Users API. The user's account must be a Gmail account, or be on a domain managed by Google Apps.
Any valid email receiving address for the app (such as xxx#APP-ID.appspotmail.com).