SecurityException is raised when trying to use JSR-179 - java-me

I want to get longitude and latitude of the phone mobile by this code:
public void commandAction(Command com, Displayable d) {
if (com == position)
{
try
{
Criteria cr = new Criteria();
cr.setHorizontalAccuracy(500);
LocationProvider lp = LocationProvider.getInstance(cr);
// get the location, one minute timeout
Location l = lp.getLocation(60);
Coordinates coords = l.getQualifiedCoordinates();
if (coords != null)
{
double longitude = coords.getLongitude();
double latitude = coords.getLatitude();
String sLong = String.valueOf(longitude);
String sLat = String.valueOf(latitude);
Tlongitude.setString(sLong);
Tlatitude.setString(sLat);
}
} catch (LocationException ex) {
Tlongitude.setString("LocationException");
Tlatitude.setString("LocationException");
} catch (InterruptedException ex) {
Tlongitude.setString("InterruptedException");
Tlatitude.setString("InterruptedException");
}
}
}
The problem is that when clicking the "position" command then a system alert is shown saying : java.lang.SecurityException : Application not authorized to access the restricted API .
So what should I do?

add the relevant permission to your application and sign it with a certificate in the corresponding security domain.
The JSR179 specification defines 7 permissions under javax.microedition.location. Choose the ones you need based on what you need your code to do.
Lucifer's solution (Verisign or Thawte) will help if the location function group is in the trusted third party security domain for the phones you want to run your code on. The phone's mobile network operator or manufacturer might have decided to put location in their security domain instead, though.
https://stackoverflow.com/q/1716755 contains a brief explanation of the MIDP security model.

You are trying to access a Location API, which a restricted API. To achieve this you must signed your mobile application with a signing certificate like Verisign,Thawte etc.
The cost of the Certificate is around 20K Indian Rupees.
You can visit my other answers here and here regarding Signing Certificate.

Related

Having REST API respect the segmented key for a field

I want to do a GET request against the Default/18.200.001/StockItem endpoint (we are about to upgrade them so I would love to know if this is different in new versions)
They have an Inventory ID with the following segmented key AAA-AAA.##.##. When I do a GET the field is returned as AAAAAA####. Is there any way to get the API to respect the designated segmented key when querying data?
As commented on the original ticket, the web service will only ever return the value, not respecting segment. I implemented a cache extension on InventoryItem that manually calculates the segment I want, and returned it thru the web service api definition
#region UsrLSInventoryIDWithKey
[PXString]
[PXUIField(DisplayName = "DisplayName")]
public string UsrLSInventoryIDWithKey
{
[PXDependsOnFields(typeof(InventoryItem.inventoryCD))]
get
{
if ((Base.InventoryCD?.Length ?? 0) < 11) return Base.InventoryCD;
return Base.InventoryCD?.Substring(0, 6) + "-" + Base.InventoryCD?.Substring(5, 5);
}
}

DDD: Syncing bounded contexts causing different domain behavior/logic

I am currently working on a DDD system that is composed out of several bounded contexts. 2 of them are:
Context "account management": Only staff members are allowed to work here. The idea is to manage customer accounts (like address, phone numbers, contacts etc etc) and to verify the account of a customer (basically checking if the data the customer supplied is valid).
Context "website": I can login as a customer and edit my data (change my address for example)
Here is the issue:
A user logged in into the account management context is per definition an employee. So I can assume that changes made here are "trustworthy" in the sense of "the data is verified". A simplified variant of the appservice looks like this:
class AccountAppService
{
public function changeAddress(string $accountId, string $address) : void
{
$account = $this->accountRepository->ofId(new Guid($accountId));
$account->changeAddress(new Address($address));
}
{
This is the appservice I am calling when an employee is changing an address. Note that there is no IdentityService that I inject/use in order to know who the employee is as this is not interesting here. The Account entity would emit an AccountAddressChanged event after successfully calling its changeAddress() method like so
class Account implements Entity
{
public function changeAddress(Address $address) : void
{
$this->address = $address;
DomainEventSubscriber::instance()->publish(new AccountAddressChanged($this));
}
}
But I also need to reflect changes as soon as a customer edits data on the website. I plan to do this async via events a la "AccountAddressChangedViaWebsite". The account management context will subscribe and handle that event, setting the corresponding account to "unverified" again. So a simplified subscriber of the account management context could look like:
class AccountAddressChangedViaWebsiteSubscriber
{
public function handle(AccountAddressChangedViaWebsite $event) : void
{
$accountId = $event->accountId();
$address = $event->getAddress();
$this->accountService->changeAddress($accountId, $address);
}
}
Now the question: Employees call the appservice directly, customers via subscribers. If we say "we have to reverify an account after the customer updates his data" it sounds like a domain concept.
Domain concepts fit into entities or domain services, but not into application services or subscribers for what I know. It implies to me that the following should be avoided (note the last line calling unverifyAccount()):
class AccountAddressChangedViaWebsiteSubscriber
{
public function handle(AccountAddressChangedViaWebsite $event) : void
{
$accountId = $event->accountId();
$address = $event->getAddress();
$this->accountService->changeAddress($accountId, $address);
$this->accountService->unverifyAccount($accountId);
}
}
This is domain logic that is somewhat hidden in a subscriber which seems odd. I have the gut feeling that this should be the responsibility of a domain service, but how would the domain service know that it is called by an external event (via subscriber) or a command?
I could pass a sort of "Originator" ValueObject that tells me wheter the user causing this is an employee or an external system. Example:
class OriginatorService
{
public function changeAddress(Originator $originator, Account $account, Address $address) : void
{
$account->changeAddress($address);
if(($originator instanceof Employee) === false) {
$account->unverify();
}
}
}
Here I delegate the responsibility of what to do to a domain service. But might double dispatching the OriginatorService into the Account entity be a good solution? This way the entity could check who caused the change via asking the passed in originatorService and could unverify itself.
I guess I am going down the DDD rabbit hole here, but what are your experiences/best practises in such a case?
The simplest answer is probably introduce UnverifiedAddress as a concept in your model, rather than trying to treat "Address" as a universal idea with the verification bolted on as an afterthought.

Project Server Online CSOM - GeneralSecurityAccessDenied while reading TimePhase Assignments

This is my first SO question so please let me know if this question is not very clear or if I am missing anything.
FYI SO prevented me from attaching links, so sorry for all the bad formatting.
Overview
I'm trying to read (and write) the "Actual work" for a resource in Project Server Online by using the CSOM library available by Microsoft. Reading and writing the assignments and Actual work is working perfectly, as long as I am reading the assignments for the currently authenticated user. If I attempt to read this for another resource, I receive a GeneralSecurityAccessDenied error.
I've done this in the past using Impersonation, which is supposed to be called transparently in the background if the user has the StatusBrokerPermission, but it doesn't seem to be working for me. Impersonation has been removed in 2013+, so that's no longer an option.
Problem summary
The CSOM is supposed to transparently enable statusing extensions to allow status updates to be made for resources other than the currently authenticated user (as long as the user has the status broker permission). This works fine for adding new assignments, but does not work when trying to update actual TimePhased hours via the TimePhased assignments. The assignments cannot be queried, and thus, we cannot call SubmitAllStatusUpdates to submit the hours.
Research
Usage scenarios for the CSOM: https:// msdn.microsoft.com/en-us/library/office/jj163082(v=office.15).aspx#pj15_WhatTheCSOM_UsageScenarios
Impersonation Deprecated: https:// msdn.microsoft.com/en-us/library/office/ee767690(v=office.15).aspx#pj15_WhatsNew_Deprecated)
Picture: Supposed to read on behalf of another user...
People with the same problem # 1: https:// social.technet.microsoft.com/Forums/projectserver/en-US/dccdb543-18a1-4a0e-a948-5d861305516e/how-to-get-resource-assignments-summary-view-data-project-server-online-2013?forum=projectonline)
People with the same problem # 2: http:// uzzai.com/ZB43wp95/ps2013-app-how-to-read-and-update-timephased-data-with-jsom-javascript-csom.html
People with the same problem # 4: https:// social.technet.microsoft.com/Forums/Sharepoint/en-US/be27d497-e959-44b6-97cb-8f19fe0278fe/csom-how-to-set-timephase-data-on-an-assignment?forum=project2010custprog
Other things I've tried
Using the CSOM with the MsOnlineClaimsHelper to retrieve the FedAuth cookies for a user (and assigning them using the CookieContainer).
Using the REST/OData API.
a) https:// URL.sharepoint.com/sites/pwa/_api/ProjectServer/EnterpriseResources('c39ba8f1-00fe-e311-8894-00155da45f0e')/Assignments/GetTimePhaseByUrl(start='2014-12-09',end='2014-12-09')/assignments
Enabling the "StatusBrokerPermission" for the user
Unchecking the “Only allow task updates via Tasks and Timesheets.” Option within the server settings screen (Task settings and display).
Creating a SharePoint-hosted app and using JSOM code equivalent to the CSOM code above.
a) The code we wrote was JavaScript being executed from within SharePoint app, so we did not need to provide authentication. The user who was logged in had the StatusBrokerPermission.
Using a Provider-hosted SharePoint app and using the CSOM code above. We tried using all authentication methods for CSOM above, with an additional test:
a) using Fiddler to view the FedAuth cookies being set by the SharePoint app authentication, and overriding the WebRequest to manually insert the FedAuth/rtFA cookies: webRequestEventArgs.WebRequestExecutor.WebRequest.CookieContainer = getStaticCookieContainer();
Using timesheets to submit time phased data.
a) We can only create a timesheet for the currently-authenticated user, and cannot populate timesheet lines with projects / assignments not available to him (or a GeneralItemDoesNotExist error is thrown).
Manually issuing a “SubmitAllStatusUpdates” CSOM request using fiddler, as a different user.
a) The purpose of this test was to determine if we can write time phased data, even if we can’t read it.
Making sure the project was checked out to the current user.
Using administrative delegation for a resource.
Setting all available options within project permissions.
Using the Project Web UI to enter the TimePhased data for other resources.
Using SharePoint permission mode instead of Project Permission Mode.
The code
See failing code screenshot here
using System;
using System.Security;
using Microsoft.ProjectServer.Client;
using Microsoft.SharePoint.Client;
namespace ProjectOnlineActuals
{
static class Program
{
const string projectSite = "https://URL.sharepoint.com/sites/pwa/";
private const string edward = "c39ba8f1-00fe-e311-8894-00155da45f0e";
private const string admin = "8b1bcfa4-1b7f-e411-af75-00155da4630b";
static void Main(string[] args)
{
TestActuals();
}
private static void TestActuals()
{
Console.WriteLine("Attempting test # 1 (login: admin, resource: admin)");
TestActuals("admin#URL.onmicrosoft.com", "123", admin);
Console.WriteLine("Attempting test # 2 (login: admin, resource: edward)");
TestActuals("adminy#hmssoftware.onmicrosoft.com", "123", edward);
Console.ReadLine();
}
private static void TestActuals(string username, string password, string resourceID)
{
try
{
using (ProjectContext context = new ProjectContext(projectSite))
{
DateTime startDate = DateTime.Now.Date;
DateTime endDate = DateTime.Now.Date;
Login(context, username, password);
context.Load(context.Web); // Query for Web
context.ExecuteQuery(); // Execute
Guid gResourceId = new Guid(resourceID);
EnterpriseResource enterpriseResource = context.EnterpriseResources.GetByGuid(gResourceId);
context.Load(enterpriseResource, p => p.Name, p => p.Assignments, p => p.Email);
Console.Write("Loading resource...");
context.ExecuteQuery();
Console.WriteLine("done! {0}".FormatWith(enterpriseResource.Name));
Console.Write("Adding new resource assignment to collection...");
enterpriseResource.Assignments.Add(new StatusAssignmentCreationInformation
{
Comment = "testing comment - 2016-02-17",
ProjectId = new Guid("27bf182c-2339-e411-8e76-78e3b5af0525"),
Task = new StatusTaskCreationInformation
{
Start = DateTime.Now,
Finish = DateTime.Now.AddDays(2),
Name = "testing - 2016-02-17",
}
});
Console.WriteLine("done!");
Console.Write("Trying to save new resource assignment...");
enterpriseResource.Assignments.Update();
context.ExecuteQuery();
Console.WriteLine("done!");
Console.Write("Loading TimePhase...");
TimePhase timePhase = enterpriseResource.Assignments.GetTimePhase(startDate.Date, endDate.Date);
context.ExecuteQuery();
Console.WriteLine("done!");
Console.Write("Loading TimePhase assignments...");
context.Load(timePhase.Assignments);
context.ExecuteQuery();
Console.WriteLine("done! Found {0} assignments.".FormatWith(timePhase.Assignments.Count));
Console.WriteLine("Updating TimePhase assignments...");
foreach (var assignment in timePhase.Assignments)
{
Console.WriteLine("Updating assignment: {0}. ActualWork: {1}".FormatWith(assignment.Name, assignment.ActualWork));
assignment.ActualWork = "9h";
assignment.RegularWork = "3h";
assignment.RemainingWork = "0h";
}
timePhase.Assignments.SubmitAllStatusUpdates("Status update comment test 2016-02-17");
context.ExecuteQuery();
Console.WriteLine("done!");
Console.WriteLine("Success (retrieved & updated {0} time phase assignments)!".FormatWith(timePhase.Assignments.Count));
}
}
catch (Exception ex)
{
if (ex.ToString().Contains("GeneralSecurityAccessDenied"))
Console.WriteLine("ERROR! - GeneralSecurityAccessDenied");
else
throw;
}
finally
{
Console.WriteLine();
Console.WriteLine();
}
}
private static void Login(ProjectContext projContext, string username, string password)
{
var securePassword = new SecureString();
foreach (char c in password)
securePassword.AppendChar(c);
projContext.Credentials = new SharePointOnlineCredentials(username, securePassword);
}
static string FormatWith(this string str, params object[] args)
{
return String.Format(str, args);
}
}
}
Can anyone help??

Control Report Permission Based on Parameters in Reporting Services

Assume we have a report called SalesSummary for a large department. This department has many smaller teams for each product. People should be able to see information about their own product, not other teams' products. We also have one domain group for each of these teams.
Copying SalesSummary report for each team and setting the permission is not the best option since we have many products. I was thinking to use a code similar to below on RS, but it doesn't work. Apparently, System.Security.Principal.WindowsPrincipal is disabled by default on RS.
Public Function isPermitted() As Boolean
Dim Principal As New System.Security.Principal.WindowsPrincipal(System.Security.Principal.WindowsIdentity.GetCurrent())
If (Principal.IsInRole("group_prod")) Then
Return true
Else
Return false
End If
End Function
I also thought I can send the userID from RS to SQL server, and inside my SP I can use a code similar to below to query active directory. This also doesn't work due to security restriction.
SELECT
*
FROM OPENQUERY(ADSI,'SELECT cn, ADsPath FROM ''LDAP://DC=Fabricam,DC=com'' WHERE objectCategory=''group''')
Is there any easier way to achieve this goal?
Thanks for the help!
The first option you suggested (using embedded code to identify the executing user) will not be reliable. SSRS code is not necessarily executed as the user accessing the report, and may not have access to that users credentials, such as when running a subscription.
Your second approach will work, but requires the appropriate permissions for your SQL server service account to query Active Directory.
Another approach is to maintain a copy of the group membership or user permissions in a SQL table. This table can be updated by hand or with an automated process. Then you can easily incorporate this into both available parameters and core data queries.
So I ended up with this code:
PrincipalContext domain = new PrincipalContext(ContextType.Domain, "AD");
UserPrincipal user = UserPrincipal.FindByIdentity(domain, identityName);
//// if found - grab its groups
if (user != null)
{
PrincipalSearchResult<Principal> _groups = null;
int tries = 0;
//We have this while because GetGroups sometimes fails! Specially if you don't
// mention the domain in PrincipalContext
while (true)
{
try
{
_groups = user.GetGroups();
break;
}
catch (Exception ex)
{
logger.Debug("get groups failed", ex);
if (tries > 5) throw;
tries++;
}
}
// iterate over all groups, just gets groups related to this app
foreach (Principal p in _groups)
{
// make sure to add only group principals
if (p is GroupPrincipal)
{
if (p.Name.StartsWith(GROUP_IDENTIFIER))
{
this.groups.Add((GroupPrincipal)p);
this.groupNames.Add(p.Name);
}
}
}
}
Now, that you have a list of related group you can check the list to authorize the user!

Programmatically determine authentication mode

Is there a way to programmatically determine if a SharePoint 2007 web application is using Forms authentication? I guess one way might be to read it from the web.config but I was wondering if there is some property exposed in the API.
Take a look at how /_admin/Authentication.aspx does it in Central Admin:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
string g = base.Request.QueryString["WebAppId"];
this.webApp = (SPWebApplication) SPConfigurationDatabase.Local.GetObject(new Guid(g));
this.zone = (SPUrlZone) Enum.Parse(typeof(SPUrlZone), base.Request.QueryString["Zone"]);
this.lb_Zone.Text = SPHttpUtility.HtmlEncode(SPAlternateUrl.GetZoneName(this.zone));
SPIisSettings iisSettings = this.webApp.IisSettings[this.zone];
// CODE ELIDED
if (AuthenticationMode.Windows != iisSettings.AuthenticationMode)
{
if (AuthenticationMode.Forms != iisSettings.AuthenticationMode)
{
// CODE ELIDED
}
else
{
this.rdo_authForms.Checked = true;
}
// CODE ELIDED
}
}
The part you are interested in is where it uses iisSettings.AuthenticationMode to determine if it is Forms Auth or not. So the trick is to correctly obtain a reference to SPIisSettings that is relevant to your webapp and zone. Getting to that point is where all the work needs to be done.
You'll need to parameterize parts of this code so that information to identify and obtain references to the webApp and Zone are passed in.
See where it assigns his.rdo_authForms.Checked? that's how you know if it's using forms auth.
Also, this implies that you need to know which Zone of the web application you are looking at to see if Forms Authentication is enabled
Using Jon Schoning's answer, I came up with the following code to determine if the current authentication mode is forms:
if (SPContext.Current.Site.WebApplication.IisSettings[SPContext.Current.Site.Zone].AuthenticationMode == System.Web.Configuration.AuthenticationMode.Forms) { ... }

Resources